2

I want to implement the following:

Create a Kivy label inside python using add_widget() function. However, I want to benefit from the fact that the label is automatically updated when the text variable has changed (in my case self.gui_data.number). I know that I could achieve this when adding the label inside the .kv file, however this is not possible in my case since I need to build up parts of the GUI in run time.

Below you see code for a minimal example. There is a button add label which adds the label and the goal is that if one presses the decrement button, the label changes. Unfortunately this is not the case.

Any help is appreciated. Thanks!

main.py

from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.widget import Widget
  
import parameters


from kivy.properties import StringProperty
from kivy.event import EventDispatcher

  
class PongBall(Widget):
    gui_data = parameters.Data()
  
    def add_label(self):
        self.gui_data.number = self.gui_data.number + '5'
        label = Label(text=str(self.gui_data.number))
        self.ids.board.add_widget(label)
  
    def decrement(self):
        self.gui_data.number = self.gui_data.number + '6'
  
    def reset_parameters(self):
        self.gui_data.reset()

class PongApp(App):
    def build(self):
        game = PongBall()
        return game
  
if __name__ == '__main__':
    PongApp().run()

parameters.py

from kivy.properties import StringProperty
from kivy.event import EventDispatcher
  
  
class Data(EventDispatcher):
    number = StringProperty("0")
     
    def reset(self):
        self.number = "0"

pong.kv

<PongBall>:
    BoxLayout:
        orientation: "vertical"
        id: board
     
        Button:
            text: "Add label"
            on_press: root.add_label()
     
        Button:
            text: "Decrement"
            on_press: root.decrement()
     
        Button:
            text: "Reset parameters"
            on_press: root.reset_parameters()
Ivanhercaz
  • 731
  • 1
  • 11
  • 31
Yannick
  • 39
  • 3

1 Answers1

0

In order to do what you want, you need a Property that you can bind to. In the modified version of your code below, I have added a number Property to the PongBall class.

class PongBall(Widget):
    gui_data = Data()
    number = StringProperty(gui_data.number)   # Property for binding

    def add_label(self):
        self.gui_data.number = self.gui_data.number + '5'
        label = Label(text=str(self.gui_data.number))

        # bind to the number Property
        self.bind(number=partial(self.number_changed, label))
        
        self.ids.board.add_widget(label)

    def number_changed(self, label, pongball, number):
        # change the Label text
        label.text = number

    def decrement(self):
        self.gui_data.number = self.gui_data.number + '6'

    def reset_parameters(self):
John Anderson
  • 35,991
  • 4
  • 13
  • 36