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 线程上。仅仅因为做某事不安全并不意味着它在某些情况下不能正常工作(或似乎可以正常工作)。
我正在使用:
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 线程上。仅仅因为做某事不安全并不意味着它在某些情况下不能正常工作(或似乎可以正常工作)。