Search code examples
pythonpython-3.xpopupkivysleep

Kivy: How to update popup Label Text without dismiss the popup


I want to open a popup and after 3 seconds change the text of popup label.

I try this code:

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.lang import Builder
from kivy.uix.button import Button
import time

Builder.load_string('''
<SimpleButton>:
    on_press: self.fire_popup()
<SimplePopup>:
    id:pop
    size_hint: .4, .4
    auto_dismiss: True
    title: 'Hello world!!'
    Label:
        id: lbl_id
        text: 'Default Text'
''')


class SimplePopup(Popup):
    pass


class SimpleButton(Button):
    text = "Fire Popup !"

    def fire_popup(self):
        pop = SimplePopup()
        pop.open()

        time.sleep(3)
        pop.ids.lbl_id.text = "Changed Text"


class SampleApp(App):
    def build(self):
        return SimpleButton()


SampleApp().run()

But BEFORE opening popup it sleeps for 3 seconds ,change the label text and then popup will open!!

What's the problem?


Solution

  • Your code:

    time.sleep(3)
    

    Is stopping the main thread, so nothing will happen with the GUI until that code finishes. You should schedule the text change using Clock.schedule_once() like this:

    from kivy.app import App
    from kivy.clock import Clock
    from kivy.uix.popup import Popup
    from kivy.lang import Builder
    from kivy.uix.button import Button
    
    Builder.load_string('''
    <SimpleButton>:
        on_press: self.fire_popup()
    <SimplePopup>:
        id:pop
        size_hint: .4, .4
        auto_dismiss: True
        title: 'Hello world!!'
        Label:
            id: lbl_id
            text: 'Default Text'
    ''')
    
    
    class SimplePopup(Popup):
        pass
    
    
    class SimpleButton(Button):
        text = "Fire Popup !"
    
        def fire_popup(self):
            self.pop = SimplePopup()
            self.pop.open()
            Clock.schedule_once(self.change_text, 3)
    
        def change_text(self, dt):
            self.pop.ids.lbl_id.text = "Changed Text"
    
    
    class SampleApp(App):
        def build(self):
            return SimpleButton()
    
    
    SampleApp().run()