运行命令行程序的wxpython GUI

时间:2013-09-02 16:42:14

标签: python wxpython subprocess

我一直在寻找一个小时,但找不到这个答案的明确答案。

我正在尝试编写一个wxPython GUI应用程序,它有一个启动命令行工具的按钮(全部在Windows上)。该工具需要大约5分钟才能运行,并随着它的运行产生输出。

我希望GUI有一些显示输出的文本窗口。我也想杀死GUI以终止命令行进程。

我看过线程和Popen,似乎无法找出它们之间的正确连接以使其工作。任何人都能指出我一个明智的例子吗?

2 个答案:

答案 0 :(得分:1)

我写了一篇文章,在那里我做了一些你正在谈论的事情。我需要运行ping和traceroute并实时捕获它们的输出。这是文章:http://www.blog.pythonlibrary.org/2010/06/05/python-running-ping-traceroute-and-more/

基本上你需要将stdout重定向到文本控件,然后执行以下操作:

proc = subprocess.Popen("ping %s" % ip, shell=True, 
                            stdout=subprocess.PIPE) 
line = proc.stdout.readline()
print line.strip()

如您所见,我使用子进程来启动ping并读取其stdout。然后我使用strip()命令从行的开头和结尾删除额外的空格,然后再打印出来。当您进行打印时,它会被重定向到文本控件。

答案 1 :(得分:1)

我在GooeyPi应用中的wxPython中做了这件事。它运行pyInstaller命令并在textctrl中逐行捕获输出。

在主应用框架中,有一个调用OnSubmit的按钮:

def OnSubmit(self, e):
    ...
     # this is just a list of what to run on the command line, something like [python, pyinstaller.py, myscript.py, --someflag, --someother flag]
    flags = util.getflags(self.fbb.GetValue())
    for line in self.CallInstaller(flags): # generator function that yields a line
        self.txtresults.AppendText(line) # which is output to the txtresults widget here

CallInstaller执行命令的实际运行,产生一行以及运行wx.Yield(),因此屏幕不会冻得太厉害。你可以将它移动到自己的线程,但我没有打扰。

def CallInstaller(self, flags):
        # simple subprocess.Popen call, outputs both stdout and stderr to pipe
        p = subprocess.Popen(flags, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        while(True): 
            retcode = p.poll() # waits for a return code, until we get one..
            line = p.stdout.readline() # we get any output
            wx.Yield() # we give the GUI a chance to breathe
            yield line # and we yield a line
            if(retcode is not None): # if we get a retcode, the loop ends, hooray!
                yield ("Pyinstaller returned return code: {}".format(retcode))
                break