简单的 wxPython 进程事件发布
我正在尝试创建一个窗口,用来接收来自一个进程的简单事件通知。以下是我目前写的代码:
import wx, wx.lib.newevent, time, sys
from multiprocessing import Process
size_width = 320
size_height = 240
background_color = (226,223,206)
SomeNewEvent, EVT_SOME_NEW_EVENT = wx.lib.newevent.NewEvent()
class StatusWindow(wx.Frame):
def __init__(self, parent):
super(StatusWindow, self).__init__(parent, title='Monitor', size=(size_width, size_height))
self.Bind(EVT_SOME_NEW_EVENT, self.updateStatus)
staticBox = wx.StaticBox(self, label='Monitor Status:', pos=(5, 105), size=(size_width - 28, size_height/3))
self.statusLabel = wx.StaticText(staticBox, label='None', pos=(10, 35), size=(size_width, 20), style=wx.ALIGN_LEFT)
self.count = 0
self.InitUI()
self.monitor = cMonitor()
self.monitor.start()
def InitUI(self):
panel = wx.Panel(self)
self.SetBackgroundColour(background_color)
self.Centre()
self.Show()
def updateStatus(self, evt):
self.statusLabel.SetLabel(evt.attr1)
class cMonitor(Process):
def __init__(self):
super(cMonitor, self).__init__()
def run(self):
time.sleep(2)
print 'This is an update'
#create the event
evt = SomeNewEvent(attr1="Some event has just occured")
#post the event
wx.PostEvent(EVT_SOME_NEW_EVENT, evt)
if __name__ == '__main__':
app = wx.App()
window = StatusWindow(None)
app.MainLoop()
窗口是创建成功了,但这个进程似乎没有在运行,也没有正确发送事件通知。我还注意到,运行方法里的打印语句也没有显示出来。是什么原因导致这个图形界面没有更新呢?这是我参考的资料:
1 个回答
1
首先,你的代码出现了错误:
Traceback (most recent call last):
File "C:\Python27\lib\multiprocessing\process.py", line 232, in _bootstrap
self.run()
File "C:\PyProgs\stackoverflow_answers\wx_answers\wx_events1.py", line 44, in run
wx.PostEvent(EVT_SOME_NEW_EVENT, evt)
File "C:\Python27\lib\site-packages\wx-3.0-msw\wx\_core.py", line 8410, in PostEvent
return _core_.PostEvent(*args, **kwargs)
TypeError: in method 'PostEvent', expected argument 1 of type 'wxEvtHandler *'
根据文档,PostEvent(dest, event)
是用来发送一个事件到窗口或其他的 wx.EvtHandler
,让它稍后处理。但是在你的代码中,第一个参数的类型是 PyEventBinder
。你的代码应该像这样:
wx.PostEvent(self.wxWindow, evt)
这里的 self.wxWindow
是 StatusWindow
类的一个对象。不过还有另一个问题:你不能把 wxPython 对象作为多进程的参数使用(链接)。
想要实现你想要的功能,可以使用线程模块,而不是多进程:
import wx, wx.lib.newevent, time, sys
from threading import *
size_width = 320
size_height = 240
background_color = (226,223,206)
SomeNewEvent, EVT_SOME_NEW_EVENT = wx.lib.newevent.NewEvent()
class StatusWindow(wx.Frame):
def __init__(self, parent):
super(StatusWindow, self).__init__(parent, title='Monitor', size=(size_width, size_height))
self.Bind(EVT_SOME_NEW_EVENT, self.updateStatus)
staticBox = wx.StaticBox(self, label='Monitor Status:', pos=(5, 105), size=(size_width - 28, size_height/3))
self.statusLabel = wx.StaticText(staticBox, label='None', pos=(10, 35), size=(size_width, 20), style=wx.ALIGN_LEFT)
self.count = 0
self.InitUI()
# Set up event handler for any worker thread results
self.monitor = cMonitor(self)
self.monitor.start()
def InitUI(self):
panel = wx.Panel(self)
self.SetBackgroundColour(background_color)
self.Centre()
self.Show()
def updateStatus(self, evt):
self.statusLabel.SetLabel(evt.attr1)
class cMonitor(Thread):
def __init__(self, wxWindow):
super(cMonitor, self).__init__()
self.wxWindow = wxWindow
def run(self):
time.sleep(2)
print 'This is an update'
#create the event
evt = SomeNewEvent(attr1="Some event has just occured")
#post the event
wx.PostEvent(self.wxWindow, evt)
if __name__ == '__main__':
app = wx.App()
window = StatusWindow(None)
app.MainLoop()