0

countdown.exe ファイルを入手しました (このファイルのソース コードは以下にあります)。このファイルが実行されると、彼はコンソールに毎秒テキストを書き込みます。GUI Python アプリが実行されたときに、このファイルの実行を開始します。

self.countdown_process = subprocess.Popen("countdown.exe", shell=True, stdout=subprocess.PIPE)

subprocess.PIPE で stdout をリダイレクトしout_thread、このプロセスの stdout を読み取り、TextCtrl に追加するスレッドを開始します。

out_thread = OutTextThread(self.countdown_process.stdout, self.AddText)
out_thread.start()

これは私のpythonアプリの完全なコードです:

import os
import sys
import wx

import subprocess, threading

class MyFrame(wx.Frame):
    def __init__(self):
        super(MyFrame, self).__init__(None)
        self._init_ctrls()

    def _init_ctrls(self):
        self.OutText = wx.TextCtrl(id=wx.NewId(), value='', name='OutText',
                                   parent=self, pos=wx.Point(0, 0),
                                   size=wx.Size(0, 0), style=wx.TE_MULTILINE|wx.TE_RICH2)

        self.OutText.AppendText("Starting process...\n")
        self.OutText.AppendText("Waiting 10 seconds...\n")
        self.countdown_process = subprocess.Popen("countdown.exe", shell = True, stdout=subprocess.PIPE)
        out_thread = OutTextThread(self.countdown_process.stdout, self.AddText)
        out_thread.start()

    def AddText(self, text):
        self.OutText.AppendText(text)

class OutTextThread(threading.Thread):
    def __init__(self, std_out, cb):
        super(OutTextThread, self).__init__()
        self.std_out = std_out
        self.cb = cb

    def run(self):
        text = None
        while text != '':
            text = self.std_out.readline()
            self.cb(text)

if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame()
    frame.Show(True)
    app.MainLoop()

countdown.exe の C++ コードは単純です。

#include <stdio.h>
#include <time.h>

void wait ( int seconds )
{
  clock_t endwait;
  endwait = clock () + seconds * CLOCKS_PER_SEC ;
  while (clock() < endwait) {}
}

int main ()
{
  int n;
  printf ("Starting countdown...\n");
  for (n=10; n>0; n--)
  {
    printf ("%d\n",n);
    wait (1);
  }
  printf ("FIRE!!!\n");
  return 0;
}

しかし、私にはいくつかの問題があります。私は自分のpythonアプリを起動し、10秒待つ必要があり、下の図でわかるように、countdown.exeのstdoutがTextCtrlに書き込まれるのは10秒だけです ここに画像の説明を入力 。 )。どうすればこれを行うことができますか?AddText メソッドで wx.CallAfter を使用してみました:

def AddText(self, text):
    wx.CallAfter(self.OutText.AppendText, text)

しかし、それは役に立たない。

4

1 に答える 1

1

スレッドから直接wxPythonメソッドを呼び出すことはできません。だからライン

self.cb(text)

動作しません。しかし、それをwx.CallAfterなどのスレッドセーフメソッドに入れると、機能するはずです。次のリンクを参照してください。

また、stdoutからテキストコントロールへのリダイレクトに関するチュートリアルもここに作成しました。

于 2012-06-11T13:36:38.007 に答える