2015-11-19 87 views
9

我有一個套接字客戶端,每次接收到消息時都會調用View()類。我已經按照這樣的方式分割我的代碼,以便這個類可以簡單地使用print()或任何其他顯示方法,如我所願。但是,基維似乎並不喜歡這種方法。我爲我的觀點擴展了Kivy的BoxLayout類,並且可以調用message()函數。該類看起來是這樣的:如何從線程更新Kivy元素?

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)) 

消息函數確實被調用,它會打印,但接口不會更新。然而,當我按下按鈕時,它會更新界面以及打印。

我已經研究過使用StringProperty修改按鈕文本,但也失敗了。就像一張紙條一樣,萬一我所做的事情是完全不可行的,我想以後會以板子的形式繪製一個由width * height按鈕組成的整個界面。

任何輸入是非常讚賞,它一直讓我瘋狂。


編輯1 * 我跟隨了幾條評論,並嘗試了幾件事。我已經添加了 Clock課程,並安排了 Viewupdate()方法。更新方法只是簡單地改變幾個元素的文本。我注意到它的工作原理,當我安排其,如下圖所示:

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() text屬性。週期性觸發的update()方法也可以工作,分配隨機文本。現在的問題是,它無法設置文本。這是行不通的:

def update(self, *args, **kwargs): 
    self.btn.text = self.text 

我一定在別處做錯了,有什麼建議嗎?


EDIT 2 * 我試圖調試的錯誤是 here

+0

您不能修改主線程以外的線程的UI元素或屬性。查看Kivy'''Clock'''類來調度函數以在mainthread上運行。 – bj0

+0

除了@ bj0的回答,您可以使用'@ mainthread'裝飾器將此方法自動應用於函數。 – inclement

+0

嘿,我已經編輯了這篇文章進一步的調查結果。我很感激幫助,並且使用'Clock()'的建議,但是如上所述,它仍然不完全正常工作。 – timur

回答

3

既然你沒有發佈一個完整的工作示例,我只能猜測你在做什麼。看起來你在一個線程上有一個事件(傳入消息),並且當發生這種情況時你想顯示一些文本。您需要將UI更新「推送」至主線程,但您不需要執行定期更新,您可以使用Clock.schedule_once安排一次性調用Clock

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裝飾做「推到主線程」:

@mainthread 
def update(self, text): 
    self.btn.text = text 

def message(self, message): 
    update(message) 

這樣一來,只要您撥打update它會在主線程上執行。

+0

我的意圖是不發佈完整的工作示例,因爲這是作業的一部分,我不想讓我的作品被抄襲。我已經在GitHub上公佈了回購,可以在這裏找到(https://github.com/TimurKiyivinski/falampous-coconut-appreciator)。自從我刪除了時鐘方法並重新使用'@ mainthread'。你正在尋找的文件是'client.py'。 – timur

+0

通常,當您不想(或不能)發佈您正在使用的代碼時,只需創建一個具有您嘗試解決的問題的最簡單的裸機應用程序。它有助於人們重現您的問題。 – bj0

+2

好吧,在瀏覽你的代碼後,它看起來不像Kivy問題,而是一個'''multiprocessing'''問題。單獨的進程不共享內存,因此很多對象之間的引用無法正常工作。使用線程代替,它應該按照您的思維方式工作 – bj0