运行代码时更新 kivy 小部件的属性

Posted

技术标签:

【中文标题】运行代码时更新 kivy 小部件的属性【英文标题】:Update properties of a kivy widget while running code 【发布时间】:2015-01-28 13:58:07 【问题描述】:

我想在运行某些东西时更新 kivy 小部件的属性...

例子:

class app(App):
    def build(self):
        self.layout = Layout()
        self.name = Label(text = "john")
        self.layout.add_widget(self.name)
        return self.layout

    def update(self):
        for i in range(50): #keep showing the update
            self.name.text = str(i)
            #maybe some sleep here

obj = app()
obj.run()
obj.update()

这只会显示循环的最终结果。我想在循环进行时继续更新 label.text。

我寻找了类似 bind()、setter() 和 ask_update() 函数,但如果是这些函数,我不知道如何使用它们。

------------------ 编辑 -----------------------

尝试适应inclement 答案(使用时钟在其他线程中运行更新功能),我得到下面的代码试图遵循我的问题的真实想法,但仍然无法正常工作:

class main():
    def __init__(self, app):
        self.app = app

    ... some code goes here ...

    def func(self):
        Clock.schedule_once(partial(self.app.update, self.arg_1, self.arg_2), 0)

class app(App):
    def build(self):
            self.main = main(self)
            self.layout = Layout()
            self.name = Label(text = "john")
            self.layout.add_widget(self.name)
            return self.layout

    ... some code goes here ...

    def update(self, dt, arg_1, arg_2):
        self.name = arg_1
        sleep(5)
        self.name = arg_2

obj = app()
obj.run()

我需要调用func函数,并在我命令update函数中的文本更改时准确地更新标签文本。

【问题讨论】:

这里是一个例子***.com/questions/23817559/… 【参考方案1】:

您需要避免阻塞主线程。在大多数情况下,只使用 kivy 的时钟很方便。您可以执行以下操作。

from kivy.clock import Clock

class app(App):
    def build(self):
        self.layout = Layout()
        self.name = Label(text = "john")
        self.layout.add_widget(self.name)
        self.current_i = 0
        Clock.schedule_interval(self.update, 1)
        return self.layout

    def update(self, *args):
        self.name.text = str(self.current_i)
        self.current_i += 1
        if self.current_i >= 50:
            Clock.unschedule(self.update)

【讨论】:

我一直在尝试调整你的答案,但还是不行,我按照你说的编辑了我的问题。 running the update function in other thread using Clock same 线程中运行它,而你的 sleep 调用仍然阻塞了这个线程。 我要解除睡眠并找到别的东西。我会继续按照你的建议去做,让它发挥作用。谢谢您的帮助! :)【参考方案2】:

不确定是否还有人需要答案,但似乎你的错误就在这里:

def update(self, dt, arg_1, arg_2):
    self.name = arg_1
    sleep(5)
    self.name = arg_2

您可以将arg1arg2(可能是字符串)分配给小部件,这似乎没有多大意义。或者创建一个新的小部件并将其重新分配给同一个变量,这也是不正确的。相反,您可以直接分配给属性:

def update(self, dt, arg_1, arg_2):
    self.name.text = arg_1
    sleep(5)
    self.name.text = arg_2

或者您可以在主对象上创建一个 StringProperty 并将self.name.text 绑定到它,但我个人更喜欢手动更新屏幕。显式优于隐式等等。

【讨论】:

以上是关于运行代码时更新 kivy 小部件的属性的主要内容,如果未能解决你的问题,请参考以下文章

Kivy:实时更新小部件的颜色

在 kivy (python) 中更新小部件

Kivy:在 python 代码中设置小部件禁用属性

向 Kivy 添加小部件时如何确保功能正常

Kivy:获取小部件 ID 并通过唯一属性访问小部件

如何在 Kivy 中使用 Popup 运行复选框小部件?