QProcess 不会在 Windows 上启动进程(但适用于 Linux 和 OSX)
QProcess won't start process on Windows (but works on Linux and OSX)
我目前正在开发一个带有 GUI 的信号分析程序,它应该在 Linux、OSX 和 Windows 上 运行。由于某些原因,该程序不会在 Windows 上 运行,但我没有收到任何错误消息。更准确地说,我的主程序 (GUI) 无法生成应该分析数据并将结果发送到 GUI 的子进程。
我在网上唯一找到的是Windows需要
if __name__ == '__main__':
到 运行 如果它们是使用多处理模块创建的,则可以正确处理。遗憾的是,添加这部分并没有解决 Qprocess 的问题。
我写了一个非常简单的脚本,它有同样的问题,并且像我的复杂脚本一样进行通信。
这里是我的主要 GUI 进程:
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5 import uic
import pickle
class MyGuiApp(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = uic.loadUi('process_gui.ui', self)
# Set puchButtons
self.stop_pB.setEnabled(False)
self.start_pB.clicked.connect(self.start_measurement)
self.stop_pB.clicked.connect(self.stop_measurement)
# Initialising Subprocess
self.my_process = QtCore.QProcess()
self.my_process.readyReadStandardOutput.connect(self.new_data)
def start_measurement(self):
self.stop_pB.setEnabled(True)
self.start_pB.setEnabled(False)
self.my_process.start('python3', ['main_subprocess.py'])
def stop_measurement(self):
self.stop_pB.setEnabled(False)
self.start_pB.setEnabled(True)
self.my_process.terminate()
def new_data(self):
data = self.my_process.readAllStandardOutput()
# unpickle data -> string
stdout_str = pickle.loads(data)
self.label.setText(stdout_str)
if __name__=='__main__':
app = QtWidgets.QApplication(sys.argv)
mainWindow = MyGuiApp()
mainWindow.show()
sys.exit(app.exec_())
'''
这是我的子进程:
import time
import sys
import pickle
index = 0
while True:
start = time.time()
sys.stdout.buffer.write(pickle.dumps(str(index)))
sys.stdout.flush()
index = index + 1
time.sleep(0.5-(time.time()-start)) # sets loop runtime to 0.5 secs
这里是 .ui 文件,以防有人想要 运行 我的代码:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="start_pB">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stop_pB">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>DATA</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
我 运行 在 windows 10
环境中使用 VS code
编辑器。
我没有对代码进行任何更改。
我这样做了:
- 我创建了
process_gui.ui
文件
- 我创建了
main_subprocess.py
文件
- 我复制了问题中的代码
这有效。
它产生这个:
当我按下 start
按钮时,它会像这样启动一个计数器:
所以我可以确认代码在 windows 上执行 运行。
我希望这对您有所帮助,或者至少确认它确实如此 运行.
鉴于代码有效,您不应查看环境设置。
我在 qt-forum 和@D.L 的评论的帮助下解决了这个问题:https://forum.qt.io/topic/135863/qprocess-not-working-on-windows-works-fine-on-linux-and-osx/5
除了 if __name__=='__main__':
之外,还必须更改 2 项才能 运行 我在 Windows.
上的代码
- 不要调用 python3,而是给 Qprocess
python.exe
的绝对路径。请注意,即使我 运行ning python3 它在 Python3X 文件夹中被称为 python.exe
,例如:r'C:\Users\me\AppData\AppData\Local\Programs\Python\Python39\python'
- 你想要的脚本也是如此运行。为 QProcess 提供整个绝对路径,例如:
r'C:\Users\Me\Desktop\dummyfolder\main_subprocess.py
'.
由于某些原因 QProcess::terminate()
,一旦您按下 'Stop' 便会触发,但现在不起作用。子进程的状态保持在 2(进程处于 运行ning 状态,可以读写。)但是 QProcess::kill()
对我来说很好。
`
我目前正在开发一个带有 GUI 的信号分析程序,它应该在 Linux、OSX 和 Windows 上 运行。由于某些原因,该程序不会在 Windows 上 运行,但我没有收到任何错误消息。更准确地说,我的主程序 (GUI) 无法生成应该分析数据并将结果发送到 GUI 的子进程。
我在网上唯一找到的是Windows需要
if __name__ == '__main__':
到 运行 如果它们是使用多处理模块创建的,则可以正确处理。遗憾的是,添加这部分并没有解决 Qprocess 的问题。
我写了一个非常简单的脚本,它有同样的问题,并且像我的复杂脚本一样进行通信。
这里是我的主要 GUI 进程:
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5 import uic
import pickle
class MyGuiApp(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = uic.loadUi('process_gui.ui', self)
# Set puchButtons
self.stop_pB.setEnabled(False)
self.start_pB.clicked.connect(self.start_measurement)
self.stop_pB.clicked.connect(self.stop_measurement)
# Initialising Subprocess
self.my_process = QtCore.QProcess()
self.my_process.readyReadStandardOutput.connect(self.new_data)
def start_measurement(self):
self.stop_pB.setEnabled(True)
self.start_pB.setEnabled(False)
self.my_process.start('python3', ['main_subprocess.py'])
def stop_measurement(self):
self.stop_pB.setEnabled(False)
self.start_pB.setEnabled(True)
self.my_process.terminate()
def new_data(self):
data = self.my_process.readAllStandardOutput()
# unpickle data -> string
stdout_str = pickle.loads(data)
self.label.setText(stdout_str)
if __name__=='__main__':
app = QtWidgets.QApplication(sys.argv)
mainWindow = MyGuiApp()
mainWindow.show()
sys.exit(app.exec_())
'''
这是我的子进程:
import time
import sys
import pickle
index = 0
while True:
start = time.time()
sys.stdout.buffer.write(pickle.dumps(str(index)))
sys.stdout.flush()
index = index + 1
time.sleep(0.5-(time.time()-start)) # sets loop runtime to 0.5 secs
这里是 .ui 文件,以防有人想要 运行 我的代码:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="start_pB">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="stop_pB">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>DATA</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
我 运行 在 windows 10
环境中使用 VS code
编辑器。
我没有对代码进行任何更改。 我这样做了:
- 我创建了
process_gui.ui
文件 - 我创建了
main_subprocess.py
文件 - 我复制了问题中的代码
这有效。
它产生这个:
当我按下 start
按钮时,它会像这样启动一个计数器:
所以我可以确认代码在 windows 上执行 运行。 我希望这对您有所帮助,或者至少确认它确实如此 运行.
鉴于代码有效,您不应查看环境设置。
我在 qt-forum 和@D.L 的评论的帮助下解决了这个问题:https://forum.qt.io/topic/135863/qprocess-not-working-on-windows-works-fine-on-linux-and-osx/5
除了 if __name__=='__main__':
之外,还必须更改 2 项才能 运行 我在 Windows.
- 不要调用 python3,而是给 Qprocess
python.exe
的绝对路径。请注意,即使我 运行ning python3 它在 Python3X 文件夹中被称为python.exe
,例如:r'C:\Users\me\AppData\AppData\Local\Programs\Python\Python39\python'
- 你想要的脚本也是如此运行。为 QProcess 提供整个绝对路径,例如:
r'C:\Users\Me\Desktop\dummyfolder\main_subprocess.py
'.
由于某些原因 QProcess::terminate()
,一旦您按下 'Stop' 便会触发,但现在不起作用。子进程的状态保持在 2(进程处于 运行ning 状态,可以读写。)但是 QProcess::kill()
对我来说很好。
`