Python 2.7 如何从子流程stdout获取结果并在TextCtrl中实时显示?(Python 2.7-wxPython)

Python 2.7 如何从子流程stdout获取结果并在TextCtrl中实时显示?(Python 2.7-wxPython),python-2.7,subprocess,wxpython,Python 2.7,Subprocess,Wxpython,我正在使用wxPython创建GUI。我试图将subprocess.Popen的结果显示为TextCtrl,一次显示一行。由于存在大量信息,窗口在显示所有信息之前会经历一个无响应阶段。我也使用线程。 我尝试过poll、read()、readline()、itr,但输出仍然一次显示出来,而不是在窗口短暂的无响应阶段后逐行显示。如果有人能帮我解决这个问题就太好了。谢谢 如果在线程中运行子进程,则只需将对文本控件的引用传递给该线程,然后使用wxPython的线程安全方法之一调用文本控件的write方法

我正在使用wxPython创建GUI。我试图将subprocess.Popen的结果显示为TextCtrl,一次显示一行。由于存在大量信息,窗口在显示所有信息之前会经历一个无响应阶段。我也使用线程。
我尝试过poll、read()、readline()、itr,但输出仍然一次显示出来,而不是在窗口短暂的无响应阶段后逐行显示。如果有人能帮我解决这个问题就太好了。谢谢

如果在线程中运行
子进程
,则只需将对文本控件的引用传递给该线程,然后使用wxPython的线程安全方法之一调用文本控件的
write
方法,如
wx.CallAfter
。下面是一个相当简单的例子:

import subprocess
import time
import wx

from threading import Thread


class PingThread(Thread):

    def __init__(self, text_ctrl):
        Thread.__init__(self)
        self.text_ctrl = text_ctrl
        self.sentinel = True
        self.start()

    def run(self):            
        proc = subprocess.Popen("ping www.google.com",
                                     shell=True,
                                     stdout=subprocess.PIPE)
        while self.sentinel:
            line = proc.stdout.readline()
            if line.strip() == "":
                pass
            else:
                wx.CallAfter(self.text_ctrl.write, line)

            if not line: break

        proc.kill()


class MyFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, title='Redirecter')
        self.ping_thread = None

        main_sizer = wx.BoxSizer(wx.VERTICAL)

        panel = wx.Panel(self)

        self.log = wx.TextCtrl(panel, style=wx.TE_MULTILINE)

        ping_btn = wx.Button(panel, label='Ping')
        ping_btn.Bind(wx.EVT_BUTTON, self.on_ping)

        main_sizer.Add(self.log, 1, wx.ALL|wx.EXPAND, 5)
        main_sizer.Add(ping_btn, 0, wx.ALL, 5)
        panel.SetSizer(main_sizer)

        self.Bind(wx.EVT_CLOSE, self.on_close)

        self.Show()

    def on_ping(self, event):
        self.ping_thread = PingThread(self.log)

    def on_close(self, event):
        if self.ping_thread:
            self.ping_thread.sentinel = False
            self.ping_thread.join()
        self.Destroy()


if __name__ == '__main__':
    app = wx.App(False)
    frame = MyFrame()
    app.MainLoop()
您可以通过以下链接阅读有关wxPython和线程的更多信息:


由于我们不知道您在做什么,请阅读这是一个伟大的例子@MikeDriscoll。没有响应的问题已经解决了:D.我想知道是否有一种方法可以显示stdout realtime?这将非常接近实时。有什么理由你会需要它比这更快吗?出于某种原因,它仍然显示了所有的东西后,一次漫长的等待。我只是希望用户能够实时看到输出,因为这是一个漫长的过程,不希望他们认为没有任何东西在运行。这是我想要实时的唯一原因。另外,非常感谢您在这方面对我的帮助!:)我的示例在您的机器上实时工作吗?我想知道您正在运行的进程是否一次不输出一行。您可以尝试读取特定数量的字节并将其发送到文本控件。非常感谢您的建议!当我做python-u\u\ud:D时,它终于起作用了