获取要在Qt小部件中显示的子进程的stdout

时间:2013-05-27 07:31:47

标签: python qt subprocess

我正在尝试在子进程中写入stdout的内容,显示在Qt小部件中。

我正在以这种方式开始这个过程:

import subprocess

subprocess.call(["program_name", "arguments"])

我想我必须让一个类像stdout一样运行,并在调用subprocess时指出它,我试过这个:

class Log:
    def __init__(self, qtWidget):
        self.qtWidget = qtWidget

    def write(self, data):
        self.qtWidget.append(data)


# (...)

log = Log(theWidget)

sub.process.call(["program_name", "arguments"], stdout=log)

但是我收到一条错误说:AttributeError:'Log'对象没有属性'fileno'

除了重定向到一个文件然后有一个不时读取它的计时器之外,你真的不能想到任何其他想法。

[编辑]

结束了这个:

process = QProcess()
process.setProcessChannelMode( QProcess.MergedChannels )
process.start( "program_name", [ "arguments" ] )
process.readyReadStandardOutput.connect( aFunction )


# then in the function...

outputBytes = process.readAll().data()
outputUnicode = outputBytes.decode( 'utf-8' )
messageWidget.append( outputUnicode )

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

子进程模块中输入/输出流的重定向工作在较低级别,这就是为什么你只能传递具有fileno的文件类对象。

如果你想从python读取数据,你可以使用subprocess.check_output而不是subprocess.call,这将把写入进程的stdout的数据作为字节返回:

log = subprocess.check_call(["program_name", "arguments"])
...   # use log

或者您可以使用subprocess.Popen并传递stdout=subprocess.PIPE。然后,您可以从返回的objets的stdout

中读取数据
p = subprocess.Popen(["program_name", "arguments"], stdout=subprocess.PIPE)
log = subprocess.stdout.read()
...   # use log

子流程文档中应该有很多例子。


编辑:

如果您需要与Qt更紧密地集成,您还可以使用QProcess来启动程序而不是子进程模块。这将允许您使用它的读通道的readyRead信号,以便在准备好从过程中读取数据时收到通知。