【问题标题】:Non-blocking realtime redirection stdout from process to wx.TextCtrl control从进程到 wx.TextCtrl 控件的非阻塞实时重定向标准输出
【发布时间】:2012-06-10 13:50:12
【问题描述】:

我有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 的标准输出只需要 10 秒,它是用 TextCtrl 编写的,如下图所示: 我希望在 TextCtrl (self.OutText) 中实时编写 countdown.exe 的标准输出。我怎么能做到这一点? 我尝试在 AddText 方法中使用 wx.CallAfter:

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

但没用。

【问题讨论】:

    标签: python multithreading wxpython


    【解决方案1】:

    您不能直接从线程调用 wxPython 方法。所以这条线

    self.cb(text)
    

    行不通。但是如果你把它放到一个线程安全的方法中,比如 wx.CallAfter,那么它应该可以工作。请参阅以下链接:

    我还在这里写了一篇关于将内容从标准输出重定向到文本控件的教程:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-18
      相关资源
      最近更新 更多