Jakube
Jakube

Reputation: 3565

Refactor on_press into class rule

In my RootWidget I have a label and two buttons. I want to dynamically change the text of the label whenever one of the buttons is clicked.

Here's a minimal working example of how I do it at the moment.

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App

w = Builder.load_string('''
<RootWidget>:
    id: root_widget

    Label:
        id: label
        text: 'Push a button'
    Button:
        text: '1'
        on_press: label.text = self.text
    Button:
        text: '2'
        on_press: label.text = self.text
''')

class RootWidget(BoxLayout):
    pass

class MainApp(App):
    def build(self):
        return RootWidget()

if __name__ == '__main__':
    MainApp().run()

Obviously I want to refactor the line on_press: label.text = self.text. My first tries ended in

<RootWidget>:
    id: root_widget

    Label:
        id: label
        text: 'Push a button'
    MyButton:
        text: '1'
    MyButton:
        text: '2'

<MyButton>:
    on_press: label.text = self.text

But obviously the MyButton-class doesn't know the property label of the RootWidget-class. And class rules inside class rules is also not allowed.

Is there a way of accomplishing binding the on_press-action dynamically?

Upvotes: 1

Views: 47

Answers (2)

Peter Badida
Peter Badida

Reputation: 12189

It's quite simple actually, because through kv you can access parent of a widget/rule easily with self.parent, so your code would look like:

from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App

w = Builder.load_string('''
<RootWidget>:
    id: root_widget

    Label:
        id: label
        text: 'Push a button'
    But:
        text: '1'
    But:
        text: '2'
<But>:
    on_press: self.parent.label.text = self.text
''')

class RootWidget(BoxLayout):
    pass

class MainApp(App):
    def build(self):
        return RootWidget()

if __name__ == '__main__':
    MainApp().run()

Upvotes: 2

zeeMonkeez
zeeMonkeez

Reputation: 5157

You can refer to the Label like this:

<MyButton@Button>:
    on_press: self.parent.ids.label.text = self.text
<RootWidget>:
    id: root_widget

    Label:
        id: label
        text: 'Push a button'
    MyButton:
        text: '1'
    MyButton:
        text: '2'

Upvotes: 2

Related Questions