【发布时间】:2019-04-25 13:22:19
【问题描述】:
1。问题解释
我在应用程序显示其主窗口之前实例化了一个QProcess()-object。 QProcess()-instance 存储在self.__myProcess 变量中,只要您能看到主窗口,它就会一直存在。
主窗口如下所示:
当你点击按钮时,会执行以下代码:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + '\r\n'
self.__myProcess.start(command)
最后两行很清楚:命令openocd.exe 被传递给self.__myProcess 并执行。 这个可执行文件的实际作用在这里并不重要。 事实上,我可以使用任何随机的可执行文件。关键是:如果可执行文件在我的 Windows PATH 环境变量中,它就会被找到并执行。
假设可执行文件不在PATH 环境变量中。那么函数self.__add_openocd_to_env() 应该可以解决这个问题:
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\\Users\\Kristof\\programs\\openocd_0.10.0\\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
但是,我注意到它根本没有效果。我在这个函数中尝试了很多不同的东西,但它不会有任何效果。
你可以在这里找到完整的代码:
如果你安装了 Python 3 和 PyQt5,你可以简单地将代码复制粘贴到一个 .py 模块中并运行它。您应该看到带有按钮的小窗口。当然,您应该将路径“C:\Users\Kristof..”更改为计算机上有效的路径。您可以为此测试选择任何您喜欢的可执行文件。
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\\Users\\Kristof\\programs\\openocd_0.10.0\\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + '\r\n'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('\r\n', '\n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
2。我的问题
我知道在实例化 QProcess() 之前,我可以简单地将“C:\Users\Kristof\programs\openocd_0.10.0\bin”添加到我的 Windows PATH 环境变量中。但这不是重点。我想知道如何将它添加到特定QProcess()-instance 的PATH 环境变量中。如果可能,它不应该影响我软件中的任何其他QProcess()-instances,也不应该影响我以后创建的任何未来QProcess()-instances。
3。系统设置
我在 Windows 10 上使用 Python 3.7 中的 PyQt5 框架。
注意:
我刚刚尝试通过以下方式改进QProcess() 设置:
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# NEW: initialize the environment variables for self.__myProcess:
env = QProcessEnvironment.systemEnvironment()
self.__myProcess.setProcessEnvironment(env)
我满怀希望......但它仍然无法正常工作:-(
【问题讨论】:
-
我认为你误会了。您正试图影响传递给子进程的
PATH环境。你想要做的只是改变parent中的PATH环境,它需要在子进程产生之前找到你的可执行文件。如果你愿意,那么在子进程生成之后将你父级的PATH改回 。 -
嗨@JonBrave,你说得有道理。你能举个例子来说明一下吗?
标签: python python-3.x process environment-variables qprocess