仅仅使用线程更新GUI还不够吗?

2024-10-03 17:15:54 发布

您现在位置:Python中文网/ 问答频道 /正文

例如:

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,而且我百分之百肯定在某个特定的时间点上只有一个线程在更新一个特定的对象,但问题是,时不时运行一段时间后,一些对象就会消失。为什么会这样?这是否意味着GUI更新不是线程安全的?可能在某个时间点只能更新一个对象?在

添加:

好吧,wx.CallAfter公司应该是以上代码的一个很好的解决方案。但是我还有一个问题,如果按钮事件和SetLabel同时发生怎么办?虽然我看不到,但这样的事情不会带来麻烦吗?在


Tags: 对象selfidmessagedef线程labelwx
2条回答

主要要记住的是,如果不使用线程安全方法,就不应该在wxPython中更新任何内容,例如wx.CallAfter公司, wx.CallLater公司或者wx.事件后. 有关详细信息,请参见http://wiki.wxpython.org/LongRunningTaskshttp://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/。在

大多数wx方法不是线程安全的。使用wx.CallAfter公司如果要从另一个线程调用wx方法,请替换

ObjectName.SetLabel(Message)

有:

^{pr2}$

编辑:一些背景信息

在wx(和大多数其他UI平台)中,所有UI更新都在一个名为main thread(或UI thread)的线程中执行。这是为了避免线程同步对性能的影响,从而使UI更快地工作。在

但缺点是,如果我们编写代码从另一个线程更新UI,结果是未定义的。有时可能会发生,有时可能会发生其他事情。所以我们应该总是转到UI线程来做UI更新。所以我们使用CallAfter函数使UI update函数在UI线程中执行。在

UI thread in java

UI thread in C#

相关问题 更多 >