[英]Is it still not enough to simply use threads to update GUI?
例如:
class DemoFrame(wx.Frame):
def __init__(self):
Initializing
...
self.TextA = wx.StaticText(MainPanel, id = -1, label = "TextAOrWhatever")
self.TextB = wx.StaticText(MainPanel, id = -1, label = "TextBOrWhatever")
...
def StaticTextUpdating(self, ObjectName, Message):
ObjectName.SetLabel(Message)
def WorkerA(self):
while True:
Work on something
UpdatingThread = threading.Thread(target = self.StaticTextUpdating, args = (self.TextA, "Something for TextA", ))
UpdatingThread.start()
time.sleep(randomSecs)
def WorkerB(self):
while True:
Work on something
UpdatingThread = threading.Thread(target = self.StaticTextUpdating, args = (self.TextB, "Something for TextB", ))
UpdatingThread.start()
time.sleep(randomSecs)
...
def StartWorking(self):
Spawn WorkerA thread
Spawn WorkerB thread
...
如您所見,我總是在新線程中更新StaticText
,並且我100%確定在某個特定時間點只有一個線程在更新特定對象,但是問題是,不時地運行一段時間后,有些物體就消失了。 為什么會這樣呢? 這是否意味着GUI更新不是線程安全的? 也許在某個時間點只能更新一個對象?
添加:
OK,wx.CallAfter應該是上述代碼的一個很好的解決方案。 但是我還有另一個問題,如果按鈕事件和SetLabel
同時發生怎么辦? 盡管我什么都沒看到,這樣的事情不會造成麻煩嗎?
大多數wx方法都不是線程安全的。 如果要從另一個線程調用wx方法,請使用wx.CallAfter。 更換
ObjectName.SetLabel(Message)
有:
wx.CallAfter(ObjectName.SetLabel, Message)
編輯:一些背景信息
在wx(以及大多數其他UI平台)中,所有UI更新都在稱為主線程(或UI線程)的單個線程中執行。 這樣可以避免線程同步對性能的影響,從而使UI更快地工作。
但是,這樣做的缺點是,如果我們編寫代碼以從其他線程更新UI,則結果是不確定的。 有時可能會起作用,有時可能會崩潰,有時可能會發生其他事情。 因此,我們應該始終轉到UI線程進行UI更新。 因此,我們使用CallAfter函數使UI更新函數在UI線程中執行。
要記住的主要事情是,在不使用wx.CallAfter,wx.CallLater或wx.PostEvent等線程安全方法的情況下,不應在wxPython中更新任何內容。 有關更多信息,請參見http://wiki.wxpython.org/LongRunningTasks或http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/ 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.