嗨,我已经看到有很多关于此问题的问题,但是似乎没有一个问题可以回答我的疑问。
按照下面的链接,当我使用Windows时,我什至尝试过winpexpect,但是它似乎为我工作。 从ffmpeg获取实时输出以在进度条(PyQt4,stdout)中使用
我正在运行带有subprocess.Popen的子程序,并希望在pyQt小部件中看到实时结果。当前,它仅在子命令执行完成后在pyQt小部件中显示结果。我需要知道是否有办法将子进程的输出实时获取到窗口中。请参阅下面我尝试过的所有代码。
import sys import os from PyQt4 import QtGui,QtCore from threading import Thread import subprocess #from winpexpect import winspawn class EmittingStream(QtCore.QObject): textWritten = QtCore.pyqtSignal(str) def write(self, text): self.textWritten.emit(str(text)) class gui(QtGui.QMainWindow): def __init__(self): # ... super(gui, self).__init__() # Install the custom output stream sys.stdout = EmittingStream(textWritten=self.normalOutputWritten) self.initUI() def normalOutputWritten(self, text): cursor = self.textEdit.textCursor() cursor.movePosition(QtGui.QTextCursor.End) cursor.insertText(text) self.textEdit.ensureCursorVisible() def callProgram(self): command="ping 127.0.0.1" #winspawn(command) py=subprocess.Popen(command.split(),stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True) result,_=py.communicate() for line in result: print line print result def initUI(self): self.setGeometry(100,100,300,300) self.show() self.textEdit=QtGui.QTextEdit(self) self.textEdit.show() self.textEdit.setGeometry(20,40,200,200) print "changing sys.out" print "hello" thread = Thread(target = self.callProgram) thread.start() #Function Main Start def main(): app = QtGui.QApplication(sys.argv) ui=gui() sys.exit(app.exec_()) #Function Main END if __name__ == '__main__': main()
QProcess与极为相似subprocess,但是在(Py)Qt代码中使用起来更加方便。因为它利用信号/插槽。另外,它异步运行该过程,因此您无需使用QThread。
QProcess
subprocess
QThread
我已经为QProcess以下代码修改(并清除了)您的代码:
import sys from PyQt4 import QtGui,QtCore class gui(QtGui.QMainWindow): def __init__(self): super(gui, self).__init__() self.initUI() def dataReady(self): cursor = self.output.textCursor() cursor.movePosition(cursor.End) cursor.insertText(str(self.process.readAll())) self.output.ensureCursorVisible() def callProgram(self): # run the process # `start` takes the exec and a list of arguments self.process.start('ping',['127.0.0.1']) def initUI(self): # Layout are better for placing widgets layout = QtGui.QHBoxLayout() self.runButton = QtGui.QPushButton('Run') self.runButton.clicked.connect(self.callProgram) self.output = QtGui.QTextEdit() layout.addWidget(self.output) layout.addWidget(self.runButton) centralWidget = QtGui.QWidget() centralWidget.setLayout(layout) self.setCentralWidget(centralWidget) # QProcess object for external app self.process = QtCore.QProcess(self) # QProcess emits `readyRead` when there is data to be read self.process.readyRead.connect(self.dataReady) # Just to prevent accidentally running multiple times # Disable the button when process starts, and enable it when it finishes self.process.started.connect(lambda: self.runButton.setEnabled(False)) self.process.finished.connect(lambda: self.runButton.setEnabled(True)) #Function Main Start def main(): app = QtGui.QApplication(sys.argv) ui=gui() ui.show() sys.exit(app.exec_()) #Function Main END if __name__ == '__main__': main()