相当于 Kivy/KivyMD 中的 `wx.CallLater()` 或如何处理 `time.sleep()` 冻结 GUI?
Equivalent to `wx.CallLater()` in Kivy/KivyMD or how do deal with `time.sleep()` freezing the GUI?
我正在尝试使用 KivyMD
/Kivy
制作一个应用程序,我想多次更改标签的文本,每次更改之间的间隔为几秒。我最初尝试使用 time.sleep()
来执行此操作,但这完全冻结了 GUI,这导致标签发生更改,因此无法正常工作。
我看到 wxPython
有 wx.CallLater()
函数,它(如果我理解正确的话)会在一段时间内调用某个函数而不会冻结 GUI。在 this thread 中,人们在谈论线程,但它似乎在没有解决最初的问题的情况下又出现了另一个问题,所以我真的不确定这是否适用于我的情况。
那么线程化是可行的方法吗,是否有 Kivy
中的 wx.CallLater()
的等价物,或者是否有其他更好的解决方案来解决我的问题?
工作测试代码:
from kivymd.app import MDApp
from kivy.lang import Builder
import time
KV = '''
MDScreen:
MDFillRoundFlatIconButton:
id: button
icon: 'git'
on_release: app.some_func()
'''
class Test(MDApp):
def build(self):
return Builder.load_string(KV)
def some_func(self):
for i in range(3):
self.root.ids.button.text = str(3 - i)
time.sleep(3)
self.root.ids.button.text = 'Go'
Test().run()
正如 @John Anderson 所建议的那样,来自 kivy.clock
的 Clock
对象具有实现与 wx.CallLater()
.
相同的方法
from kivy.clock import Clock
# to schedule an event once:
Clock.schedule_once(lambda _: some_function(), in_x_seconds)
# to schedule an event repeatedly:
Clock.schedule_interval(lambda _: some_function(), every_x_seconds)
我正在尝试使用 KivyMD
/Kivy
制作一个应用程序,我想多次更改标签的文本,每次更改之间的间隔为几秒。我最初尝试使用 time.sleep()
来执行此操作,但这完全冻结了 GUI,这导致标签发生更改,因此无法正常工作。
我看到 wxPython
有 wx.CallLater()
函数,它(如果我理解正确的话)会在一段时间内调用某个函数而不会冻结 GUI。在 this thread 中,人们在谈论线程,但它似乎在没有解决最初的问题的情况下又出现了另一个问题,所以我真的不确定这是否适用于我的情况。
那么线程化是可行的方法吗,是否有 Kivy
中的 wx.CallLater()
的等价物,或者是否有其他更好的解决方案来解决我的问题?
工作测试代码:
from kivymd.app import MDApp
from kivy.lang import Builder
import time
KV = '''
MDScreen:
MDFillRoundFlatIconButton:
id: button
icon: 'git'
on_release: app.some_func()
'''
class Test(MDApp):
def build(self):
return Builder.load_string(KV)
def some_func(self):
for i in range(3):
self.root.ids.button.text = str(3 - i)
time.sleep(3)
self.root.ids.button.text = 'Go'
Test().run()
正如 @John Anderson 所建议的那样,来自 kivy.clock
的 Clock
对象具有实现与 wx.CallLater()
.
from kivy.clock import Clock
# to schedule an event once:
Clock.schedule_once(lambda _: some_function(), in_x_seconds)
# to schedule an event repeatedly:
Clock.schedule_interval(lambda _: some_function(), every_x_seconds)