How can I add a path to the QProcess PATH environment variable? (PyQt5 on Python 3.7)












0














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:



enter image description here



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 :-(
 

 










share|improve this question




















  • 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












  • Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
    – K.Mulier
    Nov 23 at 10:29
















0














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:



enter image description here



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 :-(
 

 










share|improve this question




















  • 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












  • Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
    – K.Mulier
    Nov 23 at 10:29














0












0








0







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:



enter image description here



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 :-(
 

 










share|improve this question















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:



enter image description here



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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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














  • 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












  • 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












1 Answer
1






active

oldest

votes


















1














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!






share|improve this answer





















  • 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










  • 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











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
});


}
});














draft saved

draft discarded


















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









1














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!






share|improve this answer





















  • 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










  • 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
















1














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!






share|improve this answer





















  • 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










  • 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














1












1








1






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!






share|improve this answer












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!







share|improve this answer












share|improve this answer



share|improve this answer










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 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










  • 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


















  • 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










  • 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
















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


















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

What visual should I use to simply compare current year value vs last year in Power BI desktop

How to ignore python UserWarning in pytest?

Alexandru Averescu