[英]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.