繁体   English   中英

wxPython,从子进程中实时捕获 output

[英]wxPython, capturing an output from subprocess in real-time

我正在开发 wxPython 中的应用程序,这是一个命令行实用程序的 GUI。 在 GUI 中有一个文本控件,它应该显示来自应用程序的 output。 我正在使用子进程启动 shell 命令,但在它完成之前我没有得到任何 output 。

我尝试了几种解决方案,但似乎都没有奏效。 以下是我目前正在使用的代码(更新):

       def onOk(self,event):        
        self.getControl('infotxt').Clear()
        try:
            thread = threading.Thread(target=self.run)
            thread.setDaemon(True)
            thread.start()

        except Exception:
            print 'Error starting thread'    

    def run(self):    
        args = dict()
        # creating a command to execute...

        cmd = ["aplcorr", "-vvfile", args['vvfile'], "-navfile", args['navfile'], "-lev1file", args['lev1file'], "-dem", args['dem'], "-igmfile", args['outfile']]

        proc = subprocess.Popen(' '.join(cmd), shell=True, stdout=subprocess.PIPE, stderr.subprocess.PIPE)         

        print
        while True:
            line = proc.stdout.readline()
            wx.Yield()
            if line.strip() == "":
                pass
            else:                
                print line.strip()                
            if not line: break
        proc.wait()

class RedirectInfoText:
    """ Class to redirect stdout text """
    def __init__(self,wxTextCtrl):
        self.out=wxTextCtrl

    def write(self,string):
        self.out.WriteText(string)

class RedirectErrorText:
    """ Class to redirect stderr text """    
    def __init__(self,wxTextCtrl):
        self.out.SetDefailtStyle(wx.TextAttr())
        self.out=wxTextCtrl

    def write(self,string):
        self.out.SetDefaultStyle(wx.TextAttr(wx.RED))
        self.out.WriteText(string)

特别是我将需要实时 output 来创建进度条。

编辑:根据 Mike Driscoll 的建议,我更改了代码。 它有时似乎有效,但大多数时候我遇到以下错误之一:

(python:7698): Gtk-CRITICAL **: gtk_text_layout_real_invalidate: 断言 `layout->wrap_loop_count == 0' 失败

或者

(python:7893):Gtk-WARNING **:无效的文本缓冲区迭代器:迭代器未初始化,或者缓冲区中的字符/pixbufs/widgets自迭代器创建以来已被修改。 您必须使用标记、字符编号或行号来跨缓冲区修改保留 position。 您可以在不使迭代器失效的情况下应用标记和插入标记,但是任何影响“可索引”缓冲区内容(可以通过字符偏移量引用的内容)的突变都会使所有未完成的迭代器失效分段错误(核心转储)

有什么线索吗?

问题是因为您正在尝试 wx.Yield 并从运行进程的线程的上下文中更新 output 小部件,而不是从 GUI 线程进行更新。

  1. 由于您是从线程运行进程,因此不需要调用 wx.Yield,因为您没有阻塞 GUI 线程,因此任何未决的 UI 事件都应该正常处理。

  2. 查看 wx.PyOnDemandOutputWindow class 以了解如何处理源自非 GUI 线程的打印或其他 output 的示例。

这可能有点棘手,但我想出了一种方法,我在这里写过: http://www.blog.pythonlibrary.org/2010/06/05/python-running-ping-traceroute-and-更多的/

设置文本的重定向后,您只需要执行以下操作:

def pingIP(self, ip):
    proc = subprocess.Popen("ping %s" % ip, shell=True,
                            stdout=subprocess.PIPE)
    print
    while True:
        line = proc.stdout.readline()
        wx.Yield()
        if line.strip() == "":
            pass
        else:
            print line.strip()
        if not line: break
    proc.wait()

这篇文章也展示了如何重定向文本。 希望这会有所帮助!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM