我想运行几个命令,并使用PyQt5按时间和时间顺序获取stdout和stderr。所以我写了如下代码。
test_ui.py
import sys
import subprocess
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QVBoxLayout
from PyQt5.QtWidgets import QPushButton, QTextEdit
from worker import Worker
class TestUI(QWidget):
def __init__(self):
super().__init__()
self.worker = Worker()
self.btn1 = QPushButton("Button1")
self.btn2 = QPushButton("Button2")
self.btn3 = QPushButton("Button3")
self.result = QTextEdit()
self.init_ui()
def init_ui(self):
self.btn1.clicked.connect(self.press_btn1)
self.btn2.clicked.connect(self.press_btn2)
self.btn3.clicked.connect(self.press_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 press_btn1(self):
command1 = "dir"
path = "./"
proc = self.worker.run_command(command1, path)
self.logging(proc)
def press_btn2(self):
command2 = "cd"
path = "./"
proc = self.worker.run_command(command2, path)
self.logging(proc)
def press_btn3(self):
command3 = "whoami"
path = "./"
proc = self.worker.run_command(command3, path)
self.logging(proc)
def logging(self, proc):
while proc.poll() is None:
out = proc.stdout.readline()
if out != "":
self.result.append(out.strip())
err = proc.stderr.readline()
if err != "":
self.result.append(err.strip())
if __name__ == "__main__":
APP = QApplication(sys.argv)
ex = TestUI()
sys.exit(APP.exec_())
worker.py
import subprocess
class Worker:
def run_command(self, cmd, path):
proc = subprocess.Popen(
cmd,
cwd=path,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True,
universal_newlines=True,
)
return proc
这是一个有助于理解的示例。我要执行的实际功能需要花费很长时间才能执行,并且具有超过100行的stdout和stderr。该应用程序还有更多命令。
但是我必须等到完成为止才能看到输出。
输出可以从run_command()函数打印,也可以从每个调用者函数打印并返回输出。
在处理命令期间,我将禁用按钮。而且,我将在命令完成后启用按钮。
但是,每次用户按下按钮时,都必须执行命令。
但是,我对PyQt5的多线程不熟悉。请帮助我。