Update properties of a kivy widget while running code

12,637

You need to avoid blocking the main thread. In most cases, it's convenient to just use kivy's clock. You can do something like the following.

from kivy.clock import Clock

class app(App):
    def build(self):
        self.layout = Layout()
        self.name = Label(text = "john")
        self.layout.add_widget(self.name)
        self.current_i = 0
        Clock.schedule_interval(self.update, 1)
        return self.layout

    def update(self, *args):
        self.name.text = str(self.current_i)
        self.current_i += 1
        if self.current_i >= 50:
            Clock.unschedule(self.update)
Share:
12,637
João Paulo
Author by

João Paulo

Just looking for nice answers...

Updated on June 22, 2022

Comments

  • João Paulo
    João Paulo almost 2 years

    I want to update the properties of a kivy widget while running something...

    Example:

    class app(App):
        def build(self):
            self.layout = Layout()
            self.name = Label(text = "john")
            self.layout.add_widget(self.name)
            return self.layout
    
        def update(self):
            for i in range(50): #keep showing the update
                self.name.text = str(i)
                #maybe some sleep here
    
    obj = app()
    obj.run()
    obj.update()
    

    This is gonna show me only the final result of the loop. I'd like to keep updating the label.text while the loop goes.

    I looked for something like the bind(), setter() and ask_update() functions, but if are these funcs, I didn't get how to use them.

    ------------------ EDIT -----------------------

    Trying to adapt to inclement answer (running the update function in other thread using Clock), I got the code below trying to follow the real idea of my problem, but still not working:

    class main():
        def __init__(self, app):
            self.app = app
    
        ... some code goes here ...
    
        def func(self):
            Clock.schedule_once(partial(self.app.update, self.arg_1, self.arg_2), 0)
    
    class app(App):
        def build(self):
                self.main = main(self)
                self.layout = Layout()
                self.name = Label(text = "john")
                self.layout.add_widget(self.name)
                return self.layout
    
        ... some code goes here ...
    
        def update(self, dt, arg_1, arg_2):
            self.name = arg_1
            sleep(5)
            self.name = arg_2
    
    obj = app()
    obj.run()
    

    I need to call the funcfunction and make it update the label text exactly when I order the text change in update function.

  • João Paulo
    João Paulo over 9 years
    I've been trying to adapt your answer, but still not working, I edited my question following what you said.
  • inclement
    inclement over 9 years
    running the update function in other thread using Clock <- Clock runs it in the same thread, and your sleep call still blocks this thread.
  • João Paulo
    João Paulo over 9 years
    I'm gonna remove the sleep and find something else. I'll keep trying to do as you suggested to make it works. Thanks for the help! :)