我为我的应用程序设计了一个GUI,单击按钮后,我连接了我的自定义函数,其中我调用bash命令以同时运行2个Python脚本。这两个脚本都是Qt应用程序。我有一个名为“开始”的按钮来运行bash命令。但是,一旦单击按钮,两个应用程序都启动,但我的GUI冻结。另外,我有一个“停止”按钮来停止这些应用程序,但是GUI冻结,并且我无法使用GUI进行任何操作。我在做什么错了?
我尝试了多种选项来同时运行2个脚本,但是命令python3 script1.py & python3 script2.py &
对我来说效果很好。还有其他方法吗? os.system()
或subprocess.call()
不适用于我。有什么有效的方法吗?
这是我的UI的主要代码。
class MainApp(QtWidgets.QMainWindow, mainui.Ui_MainWindow):
def __init__(self, parent=None):
super(MainApp, self).__init__(parent)
self.setupUi(self)
self.exitapp()
self.startApp()
def multipleopen(self):
self.output = subprocess.check_output(['bash', '-c',
"python3 guiGO.py & python3 liveSpectogram.py &"])
def startApp(self):
self.start.clicked.connect(self.multipleopen)
def exitapp(self):
self.exit.clicked.connect(QtCore.QCoreApplication.instance().quit)
我希望在单击“开始”按钮时启动两个应用程序,并通过单击“停止”按钮将其停止。但是单击“开始”按钮后,GUI冻结,除了关闭正在运行的应用程序并关闭GUI窗口之外,我无能为力
GUI变得无响应
我必须强制退出GUI
我必须使用“停止”按钮手动停止脚本
答案 0 :(得分:2)
函数subprocess.check_output()
被阻止,因此它将通过冻结应用程序来防止GUI的事件循环执行其工作,而应使用QProcess
:
class MainApp(QtWidgets.QMainWindow, mainui.Ui_MainWindow):
def __init__(self, parent=None):
super(MainApp, self).__init__(parent)
self.setupUi(self)
self._process = QtCore.QProcess(self)
self._process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
self._process.setProcessChannelMode(QtCore.QProcess.ForwardedChannels)
self._process.setProgram('bash')
self._process.setArguments(['-c', 'python3 guiGO.py & python3 liveSpectogram.py &'])
self.exitapp()
self.startApp()
# read prints
def on_readyReadStandardOutput(self):
self.output = self._process.readAllStandardOutput()
print(self.output)
def startApp(self):
self.start.clicked.connect(self._process.start)
def exitapp(self):
self.exit.clicked.connect(self.close)
更新:
如果您想杀死python脚本,则必须使用pkill命令通过bash进行,因为这是启动它们的脚本。您应该在代码的哪一部分叫pkill?,可能的一部分是closeEvent方法。
from PyQt5 import QtCore, QtWidgets
class MainApp(QtWidgets.QMainWindow): #, mainui.Ui_MainWindow):
def __init__(self, parent=None):
super(MainApp, self).__init__(parent)
self.setupUi(self)
self._scripts = ("guiGO.py", "liveSpectogram.py")
self._processes = []
for script in self._scripts:
process = QtCore.QProcess(self)
process.readyReadStandardOutput.connect(self.on_readyReadStandardOutput)
process.setProcessChannelMode(QtCore.QProcess.ForwardedChannels)
process.setProgram('bash')
process.setArguments(['-c', 'python3 {}'.format(script)])
self._processes.append(process)
self.exitapp()
self.startApp()
# read prints
def on_readyReadStandardOutput(self):
self.output = self.sender().readAllStandardOutput()
print(self.output)
def startApp(self):
for process in self._processes:
self.start.clicked.connect(process.start)
def exitapp(self):
self.exit.clicked.connect(self.close)
def closeEvent(self, event):
for script in self._scripts:
QtCore.QProcess.startDetached("bash", ["-c", "pkill -f {}".format(script)])
super(MainApp, self).closeEvent(event)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainApp()
w.show()
sys.exit(app.exec_())