問題描述
我在 for 循環期間嘗試更新標簽文本時遇到問題.有類似的條目(例如:Update properties of a kivy widget while運行代碼),但它們似乎并不完全適合我的問題(或者我錯過了重點......).我運行以下代碼:
I have an issue when I try to update a label text during a for-loop. There are similar entries (e.g.: Update properties of a kivy widget while running code) but they do not seem to fit my issue exactly (or I missed the point…). I run following 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()
*.kv
<MyBox>:
orientation: 'horizontal'
cols: 2
Label:
text: root.tobeupd
Button:
text: 'Start Update'
on_release: root.upd_ltxt()
雖然打印"語句會定期更新 shell,但標簽文本僅在 for 循環結束時更新.誰能向我解釋為什么 Kivy 會這樣工作以及我如何克服這個問題?
Whereas the ‘print’ statement updates the shell regularly, the label text updates at the end of the for-loop only. Can anyone explain to me why Kivy works this way and how I can overcome this problem?
根據 PM2Ring 和 Gugas,我更改了代碼以避免睡眠功能.如果我要求用戶在循環繼續之前輸入一些內容,問題仍然存在.這些值在 shell 中更新,但不在標簽上.
According to PM2Ring and Gugas, I changed the code in order to avoid the sleep-function. The problem remains if I ask the user to enter something before the loop can be continued. The values are updated in the shell but not on the label.
推薦答案
您可以為此使用 threading
.
當您在 kivy 中執行循環或等待輸入時,主線程正在等待,并且不會在應用程序上更新任何內容.threading
會阻止這種情況.
使用 threading
在主線程之外創建另一個線程.
示例:
You can use threading
for this.
When you do a loop or wait for an input in kivy, the main thread is waiting, and nothing will update on the app. threading
will prevent that.
Use threading
to make another thread besides the main thread.
Example:
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()
現在值得一提的是,即使第一個尚未完成,您也可以繼續按下按鈕并啟動線程.這可能是不受歡迎的行為.
這可以通過在線程開始時禁用按鈕并在結束時再次啟用它來防止.
Now its worth mentioning that you can keep pushing the button and start threads, even if the first did not finish yet. This might be an unwanted behavior.
This can be prevented by disabling the button in the beginning of the thread, and enabling it again at the end.
在kv中給按鈕一個id:
Give the button an id in kv:
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
這篇關于Kivy:標簽文本在 for 循環期間不更新的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!