2009-04-07 2 views
0

wx.Processをサブクラス化しようとしています。私は、イベントをstdoutストリームから収集されたデータでメインスレッドに戻すカスタマイズされたプロセスランチャを持っています。これは良いことですか?ここwx.Processからメインスレッドに情報を伝播させる最善の方法は何ですか?

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" 

BuildEventwx.PyEventのカスタムサブクラスです。プロセスは起動、実行、終了が正しく行われていますが、アイドルイベントにバインドされているとは限りませんが、on_idle関数は決して実行されません。

答えて

1

目的は別のプロセスのメソッドを呼び出すことではなく、プロセスが実行されるときに定期的に起動される「更新」イベントを介して別のプロセスの標準出力を親プロセスにリダイレクトすることです。

一つの解決策は、私たちは私たちのために仕事をするためにEVT_IDLEに依存しないように、定期的にプロセスの出力ストリームをポーリングするwx.Timerを使用することです(私はトラブルの火に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

wxProcessのドキュメントを見ると、私はそれがうまくいくとは思わない:wxProcessは、あなたの現在のプロセスの子として実行されている新しい独立したプロセスを作成する。そのようなプロセスでメッセージに接続されたメソッドを実行することはできません。

アイドルイベントをメインスレッドの関数またはメソッドに接続することができます。

wxThreadクラスは本当に使いたいものです。