Каков наилучший способ распространения информации из моего wx.Process обратно в мой основной поток? - PullRequest
0 голосов
/ 07 апреля 2009

Я пытаюсь создать подкласс 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 ]

1 голос
/ 07 апреля 2009

Задача состоит не в том, чтобы вызывать методы другого процесса, а в том, чтобы перенаправить стандартный вывод другого процесса обратно в родительский процесс через события «update», периодически запускаемые при выполнении процесса.

Одним из решений является использование 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 мс выходной поток считывается, упаковывается и отправляется как событие сборки.

0 голосов
/ 07 апреля 2009

Просматривая документы по wxProcess, я не думаю, что это работает таким образом: wxProcess создаст новый отдельный процесс, выполняющийся как дочерний процесс вашего текущего процесса. В таком процессе невозможно запустить методы, связанные с сообщением.

Может быть, вы можете подключить событие в режиме ожидания к функции или методу в главном потоке.

Или, возможно, класс wxThread - это то, что вы действительно хотите использовать.

...