Python 使用PyQt5运行命令并获取stdout和stderr
我想用PyQt5运行命令。我想以时间顺序实时获取标准输出和标准输出Python 使用PyQt5运行命令并获取stdout和stderr,python,pyqt,pyqt5,qprocess,Python,Pyqt,Pyqt5,Qprocess,我想用PyQt5运行命令。我想以时间顺序实时获取标准输出和标准输出 "Output 1" Waiting for 0 seconds, press a key to continue ... "Error 1" Waiting for 0 seconds, press a key to continue ... "Output 2" Waiting for 0 seconds, press a key to continue ... "Error 2" 我分为UI类和Worker类。有几
"Output 1"
Waiting for 0 seconds, press a key to continue ...
"Error 1"
Waiting for 0 seconds, press a key to continue ...
"Output 2"
Waiting for 0 seconds, press a key to continue ...
"Error 2"
我分为UI类和Worker类。有几个UI类,但为了简单起见,我只指定了一个
我试图解决这个问题,但我做不到。我无法连接辅助线程和记录器函数
测试ui.py
导入系统
导入子流程
从PyQt5.QtWidgets导入QApplication、QWidget、QHBoxLayout、QVBoxLayout
从PyQt5.QtWidgets导入QPushButton,QTextEdit
从工人进口工人
类TestUI(QWidget):
定义初始化(自):
super()。\uuuu init\uuuuu()
self.worker=worker()
self.btn1=QPushButton(“Button1”)
self.btn2=QPushButton(“Button2”)
self.btn3=QPushButton(“Button3”)
self.result=QTextEdit()
self.init_ui()
def初始用户界面(自身):
self.btn1.点击.连接(self.press_btn1)
self.btn2.单击.connect(self.press_btn2)
self.btn3.单击.连接(self.press\u btn3)
hlayout1=QHBoxLayout()
hlayout1.addWidget(self.btn1)
hlayout1.addWidget(self.btn2)
hlayout1.addWidget(self.btn3)
hlayout2=QHBoxLayout()
hlayout2.addWidget(self.result)
vlayout=QVBoxLayout()
vlayout.addLayout(hlayout1)
vlayout.addLayout(hlayout2)
self.setLayout(vlayout)
self.show()
def压力btn1(自身):
command1=“dir”
路径=“../”
self.worker.run_命令(command1,path)
self.worker.outSignal.connect(self.logging)
def压力btn2(自身):
command2=“cd”
路径=“../”
self.worker.run_命令(command2,path)
self.worker.outSignal.connect(self.logging)
def压力btn3(自身):
command3=“whoami”
路径=“../”
self.worker.run_命令(command3,path)
self.worker.outSignal.connect(self.logging)
def日志记录(self,str):
self.result.append(str.strip())
如果名称=“\uuuuu main\uuuuuuuu”:
APP=QApplication(sys.argv)
ex=TestUI()
sys.exit(APP.exec_())
worker.py
从PyQt5.QtCore导入QProcess,pyqtSignal
班主任:
外部信号=pyqtSignal(str)
errSignal=pyqtSignal(str)
定义初始化(自):
self.proc=QProcess()
def run_命令(self、cmd、path):
self.proc.setWorkingDirectory(路径)
self.proc.setProcessChannelMode(QProcess.MergedChannels)
self.proc.readyReadStandardOutput.connect(self.onReadyStandardOutput)
self.proc.finished.connect(self.proc.deleteLater)
self.proc.start(cmd)
def onReadyStandardOutput(自):
结果=self.proc.readAllStandardOutput().data().decode()
self.outSignal.emit(结果)
def OnReadyStandarderError(自身):
结果=self.proc.readAllStandardError().data().decode()
self.errSignal.emit(结果)
更新:
应用并进行以下修改仍会使代码失败:
@pyqtlot()
def压力btn1(自身):
command1=“dir”
路径=“../”
self.worker.run_命令(command1,path)
@pyqtSlot()
def压力btn2(自身):
command2=“cd”
路径=“../”
self.worker.run_命令(command2,path)
@pyqtSlot()
def压力btn3(自身):
command3=“test.bat”
路径=“../”
self.worker.run_命令(command3,path)
@pyqtSlot(str)
def日志记录(self,msg):
msg=msg.strip()
如果是味精!="":
self.result.append(msg)
测试.bat
@echo off
echo "Output 1"
timeout /t 1
1>&2 echo "Error 1"
timeout /t 1
echo "Output 2"
timeout /t 1
1>&2 echo "Error 2"
批处理文件问题 这是通过命令提示符运行它时的结果 它每秒实时输出一行
"Output 1"
Waiting for 0 seconds, press a key to continue ...
"Error 1"
Waiting for 0 seconds, press a key to continue ...
"Output 2"
Waiting for 0 seconds, press a key to continue ...
"Error 2"
这是应用程序的结果
3秒后输出整行。时间顺序不对
"Output 1"
Waiting for 1 seconds, press a key to continue ...0
Waiting for 1 seconds, press a key to continue ...0
"Output 2"
Waiting for 1 seconds, press a key to continue ...0
"Error 1"
"Error 2"
我不完全确定,但您可以尝试让Worker从QObject或QWidget继承。我相当肯定,这是用户创建的类发出信号工作所必需的 您有以下错误:
- 这些信号只在QoObject中工作,因此Worker必须从QoObject继承
- 建议QProcess不要成为该类的成员,因为我们说任务1正在执行,在未完成的情况下,您尝试执行任务2,以便任务1将被替换,这不是您想要的,相反,QProcess可以作为Worker的子进程来完成,这样您的生命周期就不局限于创建它的方法
- 如果要分别监视stderr和stdio输出,则不应将processChannelMode与QProcess::MergedChannels连接,因为这将连接两个输出。另一方面,如果消除了上述情况,则必须使用readyreadstandardror信号来了解何时修改stderr
- 由于QProcess不是该类的成员,因此很难在onReadyStandardOutput和onReadyStandardError中获取QProcess,但为此,必须使用具有发出信号的对象的sender()方法
- 信号和插槽之间的连接只能进行一次,在您的情况下,您可以按一下btn1、btn2和btn3进行连接,这样您将获得3倍相同的信息
- 不要使用
,因为它是一个内置函数str
从PyQt5.QtCore导入QObject、QProcess、pyqtSignal、pyqtSlot
班级工作人员(QObject):
外部信号=pyqtSignal(str)
errSignal=pyqtSignal(str)
def run_命令(self、cmd、path):
proc=QProcess(自)
进程setWorkingDirectory(路径)
proc.readyReadStandardOutput.connect(self.onReadyStandardOutput)
进程readyReadStandardError.connect(self.onReadyStandarderError)
proc.finished.connect(proc.deleteLater)
程序启动(cmd)
@pyqtSlot()
def onReadyStandardOutput(自):
过程=