Kivy:标签文本在for循环期间不会更新
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kivy:标签文本在for循环期间不会更新相关的知识,希望对你有一定的参考价值。
当我尝试在for循环期间更新标签文本时,我遇到了问题。有类似的条目(例如:Update properties of a kivy widget while running code),但它们似乎并不完全符合我的问题(或者我错过了重点......)。我运行以下代码:
*的.py:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
#from time import sleep
class MyBox(BoxLayout):
tobeupd = StringProperty()
def __init__(self,*args,**kwargs):
super(MyBox,self).__init__(*args,**kwargs)
self.tobeupd = '#'
def upd_ltxt(self):
for i in range(1,10):
self.tobeupd = str(i)
print(self.tobeupd)
input('Write something: ') # new line, see edit below
#sleep(0.5)
class updApp(App):
def build(self):
return MyBox()
if __name__ == '__main__':
updApp().run()
季
<MyBox>:
orientation: 'horizontal'
cols: 2
Label:
text: root.tobeupd
Button:
text: 'Start Update'
on_release: root.upd_ltxt()
'print'语句定期更新shell,而标签文本仅在for循环结束时更新。任何人都可以向我解释为什么Kivy以这种方式工作以及我如何克服这个问题?
编辑:根据PM2Ring和Gugas,我改变了代码以避免睡眠功能。如果我要求用户在循环继续之前输入内容,问题仍然存在。值在shell中更新,但不在标签上更新。
你可以使用threading
。
当您执行循环或等待kivy中的输入时,主线程正在等待,并且应用程序上不会更新任何内容。 threading
将阻止这一点。
使用threading
创建除主线程之外的另一个线程。
例:
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import StringProperty
from kivy.lang import Builder
import threading
Builder.load_string('''
<MyBox>:
orientation: 'horizontal'
cols: 2
Label:
text: root.tobeupd
Button:
text: 'Start Update'
on_release: root.upd_ltxt()
''')
class MyBox(BoxLayout):
tobeupd = StringProperty()
def __init__(self,*args,**kwargs):
super(MyBox,self).__init__(*args,**kwargs)
self.tobeupd = '#'
def upd_ltxt(self):
threading.Thread(target=self.update_label).start()
def update_label(self):
for i in range(1,10):
print(self.tobeupd)
self.tobeupd = str(i)
input('Write something: ') # new line, see edit below
class updApp(App):
def build(self):
return MyBox()
if __name__ == '__main__':
updApp().run()
现在值得一提的是,你可以继续按下按钮并启动线程,即使第一个尚未完成。这可能是一种不受欢迎的行为。 这可以通过禁用线程开头的按钮,并在结束时再次启用它来防止。
在kv中为按钮指定一个id:
Button:
id: updatebutton
text: 'Start Update'
on_release: root.upd_ltxt()
并在线程中这样做:
def update_label(self):
self.ids.updatebutton.disabled = True
for i in range(1,10):
self.tobeupd = str(i)
input('Write something: ')
self.ids.updatebutton.disabled = False
您还可以使用Kivys clock
Class,它是一个事件调度程序。它将安排一个事件,这是一个功能。例如,更新标签文本。
from kivy.clock import Clock
def to_be_called_back(self,dt):
print("This function should be periodically executed")
def do_the_loop(self):
Clock.schedule_interval(self.to_be_called(),0.5)
这里函数to_be_called()
将每0.5秒调用一次。 dt
变量代表deltatime,而Clock类显然需要它(没有它,它使我的代码出现问题)
我仍然将do_the_loop()
函数放入一个单独的线程中。但这就是kivy为它提供的东西。 If you want to know more about the clock Class head over here.
以上是关于Kivy:标签文本在for循环期间不会更新的主要内容,如果未能解决你的问题,请参考以下文章
在 Kivy for Python 中按下按钮时更新标签的文本