問題描述
我有一個套接字客戶端,它每次收到消息時都會調用 View()
類.我已經以這樣一種方式拆分了我的代碼,這樣這個類就可以簡單地使用 print()
或我喜歡的任何其他顯示方法.然而,Kivy 似乎并不喜歡這種方法.我為我的視圖擴展了 Kivy 的 BoxLayout
類,并且可以調用 message()
函數.這個類看起來像這樣:
I have a socket client that calls a View()
class every time it receives a message. I've split my code in such a way such that this class can simply use print()
or any other display method, as I like. However, it seems that Kivy is not fond of this method. I've extended Kivy's BoxLayout
class for my view and can call the message()
function. The class looks something like this:
class View(BoxLayout):
def __init__(self, **kwargs):
super(View, self).__init__(**kwargs)
self.btn = Button(text='Default')
# Bind button press method
self.btn.bind(on_press=self.message)
self.add_widget(self.btn)
def message(self, message):
self.btn.text = 'Meow'
self.add_widget(Button(text='Meow'))
print(str(message))
message 函數確實被調用并打印但界面沒有更新.但是,當我按下按鈕時,它會更新界面和打印.
The message function is indeed called and it prints but the interface does not update. When I press the button however, it does update the interface as well as print.
我研究過使用 StringProperty
來修改按鈕文本,但也失敗了.順便說一句,如果我正在做的事情完全不可行,我會嘗試稍后以板的形式繪制一個由 width * height
按鈕組成的整個界面.
I've looked into using a StringProperty
to modify the button text but have failed that too. Just as a note, in case what I'm doing is completely infeasible, I'm trying to later draw an entire interface consisting of width * height
buttons, in the form of a board.
非常感謝任何意見,這讓我發瘋了.
Any input is very much appreciated, it's been driving me insane.
編輯 1*我關注了一些評論并嘗試了一些事情.我添加了一個
Clock
類并讓它從 View
安排一個 update()
方法.update 方法只是改變一些元素的文本.當我安排它時,我注意到它可以工作,如下所示:
EDIT 1* I've followed on a few comments and tried a few things out. I've added a
Clock
class and have it schedule an update()
method from View
. The update method simply changes the text of a few elements. I've noticed it works when I schedule it to, as shown below:
def update(self, *args, **kwargs):
self.btn.text = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for i in range(32))
def message(self, message):
try:
print(message)
self.text = 'sending'
except Exception as e:
print(e)
線程現在只分配文本屬性,如 message()
所示.周期性觸發的 update()
方法也可以工作,分配隨機文本.但是現在的問題是它無法設置文本.這不起作用:
The thread now simply assigns the text property as seen in message()
. The periodically triggered update()
methods works too, assigning random text. Now the issue however that it cannot set the text. This does not work:
def update(self, *args, **kwargs):
self.btn.text = self.text
我肯定在其他地方做錯了,有什么建議嗎?
I must be doing wrong elsewhere, any suggestions?
編輯 2*我要調試的錯誤是 here.
推薦答案
由于您沒有發布完整的工作示例,我只能猜測您在做什么.似乎您在線程上有一個事件(傳入消息),并且您希望在發生這種情況時顯示一些文本.您需要將 UI 更新推送"到主線程,但您不需要使用 Clock
進行 周期性 更新,您可以使用 Clock.schedule_once
.
Since you don't post a full working example, I can only guess at what your doing. It seems you have an event (incoming message) on a thread, and you want to display some text when this occurs. You need to 'push' UI updates to the main thread, but you don't need to do periodic updates with Clock
, you can just schedule one-time calls with Clock.schedule_once
.
from functools import partial
def update(self, text, *a):
self.btn.text = text
def message(self, message):
Clock.schedule_once(partial(self.update, message), 0)
如上所述,您可以使用 @mainthread
裝飾器:
As inclement mentioned, you can do this 'push to main thread' automatically with the @mainthread
decorator:
@mainthread
def update(self, text):
self.btn.text = text
def message(self, message):
update(message)
這樣,每當你調用 update
時,它都會在主線程上執行.
This way, whenever you call update
it will be executed on the main thread.
這篇關于如何從線程更新 Kivy 元素?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!