簡體   English   中英

如何實時更新 Kivy 滾動視圖 Label?

[英]How to update a Kivy Scrollview Label in real time?

對於我實際上非常簡單的 Python Kivy 問題,我真的真的需要一些幫助。 我寫了一個程序,它首先宣布計數到 5,然后應該開始從 1 計數到 5。信息應該顯示在滾動視圖標簽中。 該代碼大致完成了它的工作,但沒有逐步更新滾動視圖,而是在時間過去后一次全部更新......?有人可以幫忙嗎? 先感謝您!

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()

問題是您正在主線程上運行您的countingtofive()方法。 由於 Kivy 使用主線程來更新 GUI,因此在您釋放主線程(通過從countingtofive()方法返回)之前它不能這樣做。 這就是為什么在該方法完成之前您什么都看不到的原因。

要解決這個問題,請在另一個線程中運行countingtofive()方法,如下所示:

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

並將Button更改為綁定到start_counting_thread()方法:

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

update_scrollview()方法的一個小改動(添加@mainthread裝飾器):

@mainthread
def update_scrollview(self, newinfo):

@mainthread裝飾器強制裝飾方法在主線程上運行。 同樣可以通過使用Clock.schedule_once()來完成,但裝飾器更容易。 只有實際更新 GUI 的那段代碼必須在主線程上運行。 通常,您應該盡量避免在主線程上長時間運行方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM