How can I add a path to the QProcess PATH environment variable? (PyQt5 on Python 3.7)
1. The problem explained
I instantiate a QProcess()
-object just before the application shows its main window. The QProcess()
-instance is stored in the self.__myProcess
variable, and stays alive as long as you can see the main window.
The main window looks like this:
When you click on the button, the following code executes:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
The last two lines are quite clear: the command openocd.exe
is passed to self.__myProcess
and executes. What this executable actually does is not important here. In fact, I could use any random executable. The point is: if the executable is in my Windows PATH
environment variable, it gets found and executed.
Imagine the executable is NOT in the PATH
environment variable. Then the function self.__add_openocd_to_env()
should fix that issue:
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)
However, I've noticed it has no effect at all. I have tried a lot of different things in this function, but it just won't have any effect.
You can find the full code here:
If you have Python 3 installed with PyQt5, you can simply copy-paste the code into a .py module and run it. You should see the little window with the pushbutton. Of course you should change the path "C:UsersKristof.." to something valid on your computer. You can choose any executable you like for this test.
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" + 'rn'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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. My question
I know I could simply add "C:UsersKristofprogramsopenocd_0.10.0bin" to my Windows PATH
environment variable before instantiating the QProcess()
. But that's not the point. I want to know how to add it to the PATH
environment variable for that one specific QProcess()
-instance. If possible, it should not affect any other QProcess()
-instances around in my software, nor should it affect any future QProcess()
-instances I create later on.
3. System settings
I use the PyQt5 framework in Python 3.7 on Windows 10.
NOTE:
I've just tried to improve the QProcess()
setup in the following way:
# -------------------------------- #
# 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)
I was hopefull ... but it still won't work :-(
python python-3.x process environment-variables qprocess
add a comment |
1. The problem explained
I instantiate a QProcess()
-object just before the application shows its main window. The QProcess()
-instance is stored in the self.__myProcess
variable, and stays alive as long as you can see the main window.
The main window looks like this:
When you click on the button, the following code executes:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
The last two lines are quite clear: the command openocd.exe
is passed to self.__myProcess
and executes. What this executable actually does is not important here. In fact, I could use any random executable. The point is: if the executable is in my Windows PATH
environment variable, it gets found and executed.
Imagine the executable is NOT in the PATH
environment variable. Then the function self.__add_openocd_to_env()
should fix that issue:
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)
However, I've noticed it has no effect at all. I have tried a lot of different things in this function, but it just won't have any effect.
You can find the full code here:
If you have Python 3 installed with PyQt5, you can simply copy-paste the code into a .py module and run it. You should see the little window with the pushbutton. Of course you should change the path "C:UsersKristof.." to something valid on your computer. You can choose any executable you like for this test.
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" + 'rn'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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. My question
I know I could simply add "C:UsersKristofprogramsopenocd_0.10.0bin" to my Windows PATH
environment variable before instantiating the QProcess()
. But that's not the point. I want to know how to add it to the PATH
environment variable for that one specific QProcess()
-instance. If possible, it should not affect any other QProcess()
-instances around in my software, nor should it affect any future QProcess()
-instances I create later on.
3. System settings
I use the PyQt5 framework in Python 3.7 on Windows 10.
NOTE:
I've just tried to improve the QProcess()
setup in the following way:
# -------------------------------- #
# 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)
I was hopefull ... but it still won't work :-(
python python-3.x process environment-variables qprocess
2
I think you're misunderstanding. You are trying to affect thePATH
environment which gets passed to the sub-process. What you want to do is simply alter thePATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent'sPATH
back after the sub-process has been spawned.
– JonBrave
Nov 23 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 at 10:29
add a comment |
1. The problem explained
I instantiate a QProcess()
-object just before the application shows its main window. The QProcess()
-instance is stored in the self.__myProcess
variable, and stays alive as long as you can see the main window.
The main window looks like this:
When you click on the button, the following code executes:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
The last two lines are quite clear: the command openocd.exe
is passed to self.__myProcess
and executes. What this executable actually does is not important here. In fact, I could use any random executable. The point is: if the executable is in my Windows PATH
environment variable, it gets found and executed.
Imagine the executable is NOT in the PATH
environment variable. Then the function self.__add_openocd_to_env()
should fix that issue:
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)
However, I've noticed it has no effect at all. I have tried a lot of different things in this function, but it just won't have any effect.
You can find the full code here:
If you have Python 3 installed with PyQt5, you can simply copy-paste the code into a .py module and run it. You should see the little window with the pushbutton. Of course you should change the path "C:UsersKristof.." to something valid on your computer. You can choose any executable you like for this test.
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" + 'rn'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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. My question
I know I could simply add "C:UsersKristofprogramsopenocd_0.10.0bin" to my Windows PATH
environment variable before instantiating the QProcess()
. But that's not the point. I want to know how to add it to the PATH
environment variable for that one specific QProcess()
-instance. If possible, it should not affect any other QProcess()
-instances around in my software, nor should it affect any future QProcess()
-instances I create later on.
3. System settings
I use the PyQt5 framework in Python 3.7 on Windows 10.
NOTE:
I've just tried to improve the QProcess()
setup in the following way:
# -------------------------------- #
# 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)
I was hopefull ... but it still won't work :-(
python python-3.x process environment-variables qprocess
1. The problem explained
I instantiate a QProcess()
-object just before the application shows its main window. The QProcess()
-instance is stored in the self.__myProcess
variable, and stays alive as long as you can see the main window.
The main window looks like this:
When you click on the button, the following code executes:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
The last two lines are quite clear: the command openocd.exe
is passed to self.__myProcess
and executes. What this executable actually does is not important here. In fact, I could use any random executable. The point is: if the executable is in my Windows PATH
environment variable, it gets found and executed.
Imagine the executable is NOT in the PATH
environment variable. Then the function self.__add_openocd_to_env()
should fix that issue:
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)
However, I've noticed it has no effect at all. I have tried a lot of different things in this function, but it just won't have any effect.
You can find the full code here:
If you have Python 3 installed with PyQt5, you can simply copy-paste the code into a .py module and run it. You should see the little window with the pushbutton. Of course you should change the path "C:UsersKristof.." to something valid on your computer. You can choose any executable you like for this test.
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" + 'rn'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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. My question
I know I could simply add "C:UsersKristofprogramsopenocd_0.10.0bin" to my Windows PATH
environment variable before instantiating the QProcess()
. But that's not the point. I want to know how to add it to the PATH
environment variable for that one specific QProcess()
-instance. If possible, it should not affect any other QProcess()
-instances around in my software, nor should it affect any future QProcess()
-instances I create later on.
3. System settings
I use the PyQt5 framework in Python 3.7 on Windows 10.
NOTE:
I've just tried to improve the QProcess()
setup in the following way:
# -------------------------------- #
# 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)
I was hopefull ... but it still won't work :-(
python python-3.x process environment-variables qprocess
python python-3.x process environment-variables qprocess
edited Nov 22 at 21:37
asked Nov 22 at 21:15
K.Mulier
2,24812556
2,24812556
2
I think you're misunderstanding. You are trying to affect thePATH
environment which gets passed to the sub-process. What you want to do is simply alter thePATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent'sPATH
back after the sub-process has been spawned.
– JonBrave
Nov 23 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 at 10:29
add a comment |
2
I think you're misunderstanding. You are trying to affect thePATH
environment which gets passed to the sub-process. What you want to do is simply alter thePATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent'sPATH
back after the sub-process has been spawned.
– JonBrave
Nov 23 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 at 10:29
2
2
I think you're misunderstanding. You are trying to affect the
PATH
environment which gets passed to the sub-process. What you want to do is simply alter the PATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent's PATH
back after the sub-process has been spawned.– JonBrave
Nov 23 at 9:12
I think you're misunderstanding. You are trying to affect the
PATH
environment which gets passed to the sub-process. What you want to do is simply alter the PATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent's PATH
back after the sub-process has been spawned.– JonBrave
Nov 23 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 at 10:29
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 at 10:29
add a comment |
1 Answer
1
active
oldest
votes
Based on the comment of Mr. @JonBrave, I have written the following workaround:
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):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 at 15:54
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438065%2fhow-can-i-add-a-path-to-the-qprocess-path-environment-variable-pyqt5-on-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Based on the comment of Mr. @JonBrave, I have written the following workaround:
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):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 at 15:54
add a comment |
Based on the comment of Mr. @JonBrave, I have written the following workaround:
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):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 at 15:54
add a comment |
Based on the comment of Mr. @JonBrave, I have written the following workaround:
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):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
Based on the comment of Mr. @JonBrave, I have written the following workaround:
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):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', '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_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
answered Nov 23 at 11:02
K.Mulier
2,24812556
2,24812556
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 at 15:54
add a comment |
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 at 15:54
Looks good. Sorry, I don't have time to type an answer! You could probably call
__remove_openocd_from_env()
straight after start()
, before waitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class from QProcess
to use just for this case to avoid changing the others. Finally, you could do this from a .bat
file on your PATH
/in your current directory which changes PATH before invoking openocd.exe
, then it's in one place (and you can change the path) and you don't have to alter QProcess
... :)– JonBrave
Nov 23 at 11:45
Looks good. Sorry, I don't have time to type an answer! You could probably call
__remove_openocd_from_env()
straight after start()
, before waitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class from QProcess
to use just for this case to avoid changing the others. Finally, you could do this from a .bat
file on your PATH
/in your current directory which changes PATH before invoking openocd.exe
, then it's in one place (and you can change the path) and you don't have to alter QProcess
... :)– JonBrave
Nov 23 at 11:45
Just noticed your code's:
command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.– JonBrave
Nov 23 at 15:51
Just noticed your code's:
command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.– JonBrave
Nov 23 at 15:51
And finally, from the example you give, if you know that the
exe
is located in the directory you're adding to PATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.– JonBrave
Nov 23 at 15:54
And finally, from the example you give, if you know that the
exe
is located in the directory you're adding to PATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.– JonBrave
Nov 23 at 15:54
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438065%2fhow-can-i-add-a-path-to-the-qprocess-path-environment-variable-pyqt5-on-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
I think you're misunderstanding. You are trying to affect the
PATH
environment which gets passed to the sub-process. What you want to do is simply alter thePATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent'sPATH
back after the sub-process has been spawned.– JonBrave
Nov 23 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 at 10:29