Python:带有线程的 PubSub 和 WxPython 是否需要 wx.CallAfter?

Python: Does PubSub and WxPython with Threading require wx.CallAfter?

我正在使用:

wxPython 4.0.7.post2

Pypubsub 4.0.3

Python 3.8.1

我编写了以下示例程序:

import wx
import time
from threading import Thread
from pubsub import pub

TIME_UPDATED = "time.updated"


class MyFrame(wx.Frame):

    def __init__(self):
        super().__init__(parent=None, title="Example")
        self.text = wx.StaticText(self, label="I will display seconds elapsed!")
        self.othertext = wx.StaticText(self, label="I will Update")

        sizer = wx.BoxSizer(orient=wx.VERTICAL)
        sizer.Add(self.text)
        sizer.Add(self.othertext)
        self.SetSizer(sizer)

        self.timer = wx.Timer(self)
        pub.subscribe(self.UpdateTime, TIME_UPDATED)
        self.Bind(wx.EVT_TIMER, self.OnTime, self.timer)
        self.Show()

        self.i = 0
        self.timer.Start(500)

    def OnTime(self, _):
        self.i += 1
        self.othertext.SetLabel(str(self.i))

    def UpdateTime(self, seconds):
        self.text.SetLabel("{seconds} seconds have elapsed".format(seconds=seconds))
        self.text.Refresh()


class BackgroundThread(Thread):

    def run(self):
        time_elapsed = 0
        while True:
            # Lets sleep 1 second
            time.sleep(1)
            time_elapsed += 1
            # <<<<---- This line is what I am worried about.
            pub.sendMessage(TIME_UPDATED, seconds=time_elapsed)


if __name__ == '__main__':

    app = wx.App()
    frame = MyFrame()

    background = BackgroundThread(daemon=True)
    background.start()

    app.MainLoop()

我正在执行 pub.sendMessage(TIME_UPDATED, seconds=time_elapsed) 而没有 wx.CallAfter,它似乎工作正常。我不知道为什么。

有人可以解释一下是否还需要 wx.CallAfter 吗?

如果是,您能解释一下为什么吗?是否某些 wx 方法将某些内容放入调度队列而其他方法则没有?

是的,您仍应确保 UI 操作发生在 UI 线程上。仅仅因为做某事不安全并不意味着它在某些情况下不能正常工作(或似乎可以正常工作)。