仅仅使用线程来更新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 更新不是线程安全的?也许某个时间点只能更新一个对象?
添加:
好的,wx.CallAfter 应该是上述代码的一个很好的解决方案。但我还有一个问题,如果按钮事件和 SetLabel 同时发生怎么办?虽然我没看到,但这样的事情不是会带来麻烦吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
大多数 wx 方法都不是线程安全的。如果你想从另一个线程调用wx方法,请使用wx.CallAfter;替换
为:
编辑:一些背景信息
在 wx(以及大多数其他 UI 平台)中,所有 UI 更新都在称为主线程(或 UI 线程)的单个线程中执行。这是为了避免线程同步对性能的影响,从而使 UI 工作得更快。
但这样做的缺点是,如果我们编写代码从不同的线程更新 UI,结果是不确定的。有时它可能会工作,有时可能会崩溃,有时可能会发生其他事情。所以我们应该总是去UI线程来进行UI更新。所以我们使用CallAfter函数让UI更新函数在UI线程中执行。
java 中的 UI 线程
C# 中的 UI 线程
Most wx methods are not thread-safe. Use wx.CallAfter if you want to invoke a wx method from another thread; replace
with:
Edit: Some Background Information
In wx (And in most other UI platforms) all the UI updates get executed in a single thread called main thread (Or UI Thread). This is to make the UI work faster by avoiding the performance hit of thread synchronization.
But the down side of this is that If we write code to update the UI from a different thread the results are undefined. Sometimes it may work, sometimes it may crash, sometimes some other thing may happen. So we should always go to UI thread to do the UI updates. So we use CallAfter function to make UI update function execute in the UI thread.
UI thread in java
UI thread in C#
要记住的主要事情是,如果不使用线程安全方法,例如 wx.CallAfter、wx.CallLater 或 wx.PostEvent,则不应更新 wxPython 中的任何内容。请参阅 http://wiki.wxpython.org/LongRunningTasks 或 http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/ 了解更多信息。
The main thing to remember is that you shouldn't update anything in wxPython without using a threadsafe method, such as wx.CallAfter, wx.CallLater or wx.PostEvent. See http://wiki.wxpython.org/LongRunningTasks or http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/ for more information.