0

wx.Processstdout ストリームから収集されたデータを使用して、イベントをメイン スレッドに戻すカスタマイズされたプロセス ランチャーがあるようにサブクラス化しようとしています。これは物事を行う良い方法ですか?

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ますが、idle イベントにバインドしたはずなのに、関数が実行されません。

4

2 に答える 2

1

目的は、別のプロセスのメソッドを呼び出すことではなく、プロセスの実行時に定期的に発生する「更新」イベントを介して、別のプロセスの stdout を親プロセスにリダイレクトすることです。

解決策の 1 つは、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 ミリ秒ごとに出力ストリームが読み取られ、パッケージ化され、ビルド イベントとして出荷されます。

于 2009-04-07T12:32:47.283 に答える
0

wxProcess docs を見ると、そのようには機能しないと思います.wxProcessは、現在のプロセスの子として実行される新しい別のプロセスを作成します。このようなプロセスでメッセージに接続されたメソッドを実行することはできません。

おそらく、アイドル イベントをメイン スレッドの関数またはメソッドに接続できます。

あるいは、wxThread クラスが本当に使いたいものかもしれません。

于 2009-04-07T07:28:52.040 に答える