我正在尝试子类wx.Process
,这样我就有了一个自定义的进程启动器,它使用从stdout流收集的数据将事件激发回主线程。这是一种很好的做事方式吗?
class BuildProcess(wx.Process):
def __init__(self, cmd, notify=None):
wx.Process.__init__(self, notify)
print "Constructing a build process"
self.Bind(wx.EVT_IDLE, self.on_idle)
self.Redirect()
self.cmd = cmd
self.pid = None
def start(self):
print "Starting the process"
self.pid = wx.Execute(self.cmd, wx.EXEC_ASYNC, self)
print "Started."
def on_idle(self, evt):
print "doing the idle thing..."
stream = self.GetInputStream()
if stream.CanRead():
text = stream.read()
wx.PostEvent(self, BuildEvent(EVT_BUILD_UPDATE, self, data=text))
print text
def OnTerminate(self, *args, **kwargs):
wx.Process.OnTerminate(self, *args, **kwargs)
print "Terminating"
BuildEvent
这是wx.PyEvent
的自定义子类。该进程正在启动,运行和终止,但我的on_idle
函数永远不会执行,即使我确定我已将它绑定到空闲事件。
答案 0 :(得分:1)
目标不是调用另一个进程的方法,目标是通过在进程执行时定期触发的“update”事件将另一个进程的stdout重定向回父进程。
一种解决方案是使用wx.Timer定期轮询进程的输出流,这样我们就不依赖EVT_IDLE来为我们工作(我无法触发EVT_IDLE)
class BuildProcess(wx.Process):
def __init__(self, cmd, notify=None):
wx.Process.__init__(self, notify)
self.Redirect()
self.cmd = cmd
self.pid = None
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.on_timer)
def start(self):
wx.PostEvent(self, BuildEvent(EVT_BUILD_STARTED, self))
self.pid = wx.Execute(self.cmd, wx.EXEC_ASYNC, self)
self.timer.Start(100)
def on_timer(self, evt):
stream = self.GetInputStream()
if stream.CanRead():
text = stream.read()
wx.PostEvent(self, BuildEvent(EVT_BUILD_UPDATE, self, data=text))
def OnTerminate(self, *args, **kwargs):
print "terminating..."
stream = self.GetInputStream()
if stream.CanRead():
text = stream.read()
wx.PostEvent(self, BuildEvent(EVT_BUILD_UPDATE, self, data=text))
if self.timer:
self.timer.Stop()
wx.PostEvent(self, BuildEvent(EVT_BUILD_FINISHED, self))
通过这种方法,每100毫秒输出流被读取,打包并作为构建事件发送出去。
答案 1 :(得分:0)
从查看wxProcess文档,我认为它不会那样工作:wxProcess将创建一个新的,单独的进程作为当前进程的子进程运行。在这样的过程中,无法运行连接到消息的方法。
也许您可以将空闲事件连接到主线程中的函数或方法。
或者,可能wxThread类是您真正想要使用的。