相当于 Kivy/KivyMD 中的 `wx.CallLater()` 或者如何处理 `time.sleep()` 冻结 GUI?

Posted

技术标签:

【中文标题】相当于 Kivy/KivyMD 中的 `wx.CallLater()` 或者如何处理 `time.sleep()` 冻结 GUI?【英文标题】:Equivalent to `wx.CallLater()` in Kivy/KivyMD or how do deal with `time.sleep()` freezing the GUI? 【发布时间】:2021-09-04 11:35:32 【问题描述】:

我正在尝试使用KivyMD/Kivy 制作应用程序,并且我想多次更改标签的文本,更改之间的间隔为几秒钟。我最初尝试使用time.sleep() 执行此操作,但这完全冻结了 GUI,导致标签更改等不起作用。

我看到wxPythonwx.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()

【问题讨论】:

看看Clock.schedule_once or Clock.schedule_interval。 【参考方案1】:

正如@John Anderson 建议的那样,来自kivy.clockClock 对象具有与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)

【讨论】:

以上是关于相当于 Kivy/KivyMD 中的 `wx.CallLater()` 或者如何处理 `time.sleep()` 冻结 GUI?的主要内容,如果未能解决你的问题,请参考以下文章

第一个 Python/Kivy/KivyMD 应用程序。无法将文本字段中的数据保存到变量 + 数据绑定到 MDList

Kivy/KivyMD - 按钮没有反应

Kivy/ Kivymd 地图切换屏幕

如何通过按下按钮 kivy/kivymd/python 在另一个窗口中创建按钮

Kivy/KivyMD 应用程序在 venv 环境中运行良好,但在 exe 文件中崩溃

在数据表 Kivy/KivyMD 中动态添加一行