2009-04-07 4 views
0

Ich versuche wx.Process von der Unterklasse zu trennen, so dass ich einen benutzerdefinierten Prozessstarter habe, der Ereignisse zurück zum Hauptthread mit Daten aus dem Stdout-Stream auslöst. Ist das ein guter Weg, Dinge zu tun?Was ist der beste Weg, um Informationen aus meinem wx.Process zurück zu meinem Haupt-Thread zu propagieren?

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 hier ist eine benutzerdefinierte Unterklasse von wx.PyEvent. Der Prozess wird ordnungsgemäß gestartet, ausgeführt und beendet, aber meine on_idle-Funktion wird nie ausgeführt, obwohl ich sicher bin, dass ich sie an das Idle-Ereignis gebunden habe.

Antwort

1

Das Ziel besteht nicht darin, Methoden eines anderen Prozesses aufzurufen. Das Ziel besteht darin, die Standardausgabe eines anderen Prozesses über "update" -Ereignisse zurück in den übergeordneten Prozess umzuleiten, wenn der Prozess ausgeführt wird.

Eine Lösung ist wx.Timer zu verwenden, in regelmäßigen Abständen den Ausgangsstrom des Prozesses abzufragen, so dass wir auf EVT_IDLE verlassen Sie sich nicht für uns die Arbeit zu tun (ich hatte Mühe EVT_IDLE immer Feuer)

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)) 

Bei dieser Methode wird der Ausgabestrom alle 100 ms gelesen, verpackt und als Build-Ereignis versandt.

0

Aus dem Blick auf die WxProcess-Dokumente, ich glaube nicht, dass es so funktioniert: wxProcess wird einen neuen, separaten Prozess erstellen, der als Kind Ihres aktuellen Prozesses ausgeführt wird. In einem solchen Prozess können keine mit einer Nachricht verbundenen Methoden ausgeführt werden.

Vielleicht können Sie Ihr leeres Ereignis mit einer Funktion oder Methode in Ihrem Haupt-Thread verbinden.

Oder mayby ​​die wxThread-Klasse ist, was Sie wirklich verwenden möchten.

Verwandte Themen