简体   繁体   中英

How to update a Kivy Scrollview Label in real time?

I could really really need some help with my actually quite simple Python Kivy Problem. I wrote a program that first announces counting to 5 and then should start counting from 1 to 5. The info should be shown in a scrollview-Label. The code roughly does its job but does not update the scrollview step-by-step but all at once after time is elapsed..?can anybody please help? Thank you in advance!

import kivy
from kivy.config import Config
from kivy.app import App
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.core.window import Window
from kivy.uix.scrollview import ScrollView
import time
 
kivy.require("2.0.0")
Config.set('kivy', 'keyboard_mode', 'systemandmulti')
 
class MainMenu(GridLayout):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.cols = 1
        self.rows = 2
        
        self.infowindow = ScrollableInfo(height=Window.size[1]*0.8, size_hint_y=None)
        self.add_widget(self.infowindow)
 
        self.ButtonCheckConnection = Button(text="Start Counting to 5")
        self.ButtonCheckConnection.bind(on_press=self.countingtofive)
        self.add_widget(self.ButtonCheckConnection)
 
    def countingtofive(self, *_):
        self.infowindow.update_scrollview(f"Counting to 5 is going to start in 3 seconds")
        time.sleep(3)
        countingmaximum = 5
 
        for i in range(countingmaximum):
            currentnumber = i+1
            self.infowindow.update_scrollview(str(currentnumber))
            time.sleep(1)
 
 
 
class ScrollableInfo(ScrollView):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.layout = GridLayout(cols=1, size_hint_y=None)
        self.add_widget(self.layout)
 
        self.connectioninfo_history = Label(size_hint_y=None, markup=True)
 
        self.layout.add_widget(self.connectioninfo_history)
 
    def update_scrollview(self, newinfo):
        self.connectioninfo_history.text += '\n' + newinfo
        
        self.layout.height = self.connectioninfo_history.texture_size[1]+15
        self.connectioninfo_history.height = self.connectioninfo_history.texture_size[1]
        self.connectioninfo_history.text_size = (self.connectioninfo_history.width*0.98, None)
 
class Counting(App):
    def build(self):
        self.screen_manager = ScreenManager()
 
        self.mainmenu_page = MainMenu()
        screen = Screen(name="MainMenu")
        screen.add_widget(self.mainmenu_page)
        self.screen_manager.add_widget(screen)
 
        return self.screen_manager
 
if __name__ == "__main__":
    counting_app = Counting()
    counting_app.run()

The problem is that you are running your countingtofive() method on the main thread. Since Kivy uses the main thread to update the GUI, it cannot do that until you release the main thread (by returning from the countingtofive() method). That is why you never see anything until that method completes.

To fix that, run the countingtofive() method in another thread, like this:

def start_counting_thread(self, *args):
    Thread(target=self.countingtofive, daemon=True).start()

And change the Button to bind to the start_counting_thread() method:

    self.ButtonCheckConnection.bind(on_press=self.start_counting_thread)

And one minor change to the update_scrollview() method (add the @mainthread decorator):

@mainthread
def update_scrollview(self, newinfo):

The @mainthread decorator forces the decorated method to be run on the main thread. The same can be accomplished by using Clock.schedule_once() , but the decorator is easier. Just the piece of the code that actually updates the GUI must be run on the main thread. Generally, you should try to avoid long running methods on the main thread.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM