将信息从我的ex.Process传播回主线程​​的最佳方法是什么?

时间:2009-04-07 02:38:47

标签: python multithreading events process wxpython

我正在尝试子类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函数永远不会执行,即使我确定我已将它绑定到空闲事件。

2 个答案:

答案 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类是您真正想要使用的。