I'm trying to set an environment variable in a QT app for a QProcess that's being run. The code is below. The environment variable does not appear to be set however when inside the test. Any suggestions?
def runUbootTests(self):
env = QtCore.QProcessEnvironment.systemEnvironment()
env.insert("LINUX_ETH_ADDR", "3c:98:bf:00:00:f4")
self.process.setProcessEnvironment(env)
self.process.readyReadStandardOutput.connect(self.readReady)
self.process.start("make", ("clean", "check_uboot"))
Have you tried using http://docs.python.org/library/os.html#os.environ? This modified the environment for the current process (as can be seen in /proc as well).
This new environment should be passed along to any spawned processes as well.
The code you posted does not seem obviously wrong, and works for me.
Here's my test files and output:
Makefile:
clean:
#echo 'SHELL:' $(SHELL)
check_uboot:
#echo 'ADDR:' $(LINUX_ETH_ADDR)
test.py:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.button = QtGui.QPushButton('Test', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.button)
self.process = QtCore.QProcess(self)
def handleButton(self):
env = QtCore.QProcessEnvironment.systemEnvironment()
env.insert("LINUX_ETH_ADDR", "3c:98:bf:00:00:f4")
self.process.setProcessEnvironment(env)
self.process.readyReadStandardOutput.connect(self.readReady)
self.process.start("make", ("clean", "check_uboot"))
def readReady(self):
print str(self.process.readAllStandardOutput())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
output:
$ python2 test.py
SHELL: /bin/sh
ADDR: 3c:98:bf:00:00:f4
Related
Is there a way to change default menu title for native menu on MacOS for a simple pyqt5 app?
I'm trying to change "Python" menu entry on above image. Is there a way to rename it? Can I hide it somehow?
This code prints only "File":
menubar = self.menuBar()
for item in menubar.actions():
print(item.text())
menubar.setNativeMenuBar(False) doesn't help too (just move "File" into the MainWindow).
Update Sample app code:
from PyQt5 import QtCore, QtWidgets, uic
import sys
class Ui(QtWidgets.QMainWindow):
def __init__(self):
super(Ui, self).__init__()
# QtCore.QCoreApplication.setApplicationName('QtFoo') # doesn't work
uic.loadUi('App.ui', self)
self.show()
# app = QtWidgets.QApplication(sys.argv)
app = QtWidgets.QApplication(["MyCoolApp"])
# app.setApplicationName("QtFoo") # doesn't work
# app.setApplicationDisplayName("Display Name")
window = Ui()
app.exec()
If you are not willing to package your app, you could create a temporary symbolic link to python as described here. This link can be used to execute python apps while displaying a custom name in the title bar:
go to the location of your app (e.g. my_app.py) file in the terminal
create symbolic link (replace location to your python interpreter, replace "BeautifulNaming" with desired name)
ln -s /Users/Christian/miniconda3/bin/python BeautifulNaming
call link to python with your script
./BeautifulNaming my_app.py
The "python" in the system menu bar appears because you run the script from the python, as soon as you package the application the title will disappear. For example the following code
# FileName PyQt5MenuProblem.py
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow
class AppTest(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle("My application")
self._createMenuBar()
def _createMenuBar(self):
self.menuBar = self.menuBar()
self.menuBar.setNativeMenuBar(False)
fileMenu = self.menuBar.addMenu("&File")
editMenu = self.menuBar.addMenu("&Edit")
if __name__== "__main__":
app = QApplication(sys.argv)
plotWindow = AppTest()
plotWindow.showMaximized()
sys.exit(app.exec_())
after packaging with
pyinstaller --onefile PyQt5MenuProblem.py
looks like
Key words: MacOS, User Interface, LSUIElement, pyinstaller, pyqt5
Hope you doing well guys! I am starting a project using PyCharm and also a Virtual Env. Can someone help please?
I have these file:
main.py with the code:
from fbs_runtime.application_context.PySide2 import ApplicationContext
import sys
from package.main_window import MainWindow
if __name__ == '__main__':
appctxt = ApplicationContext() # 1. Instantiate ApplicationContext
window = MainWindow()
window.resize(250, 150)
window.show()
exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_()
sys.exit(exit_code)
I have another file main_window.py with these code:
from PySide2 import QtWidgets
class MainWindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setup_ui()
def setup_ui(self):
self.create_widgets()
self.modify_widgets()
self.create_layouts()
self.add_widgets_to_layouts()
self.setup_connections()
def create_widgets(self):
self.btn_click = QtWidgets.QPushButton("Click")
def modify_widgets(self):
pass
def create_layouts(self):
self.main_layout = QtWidgets.QVBoxLayout(self)
def add_widgets_to_layouts(self):
self.main_layout.addWidget(self.btn_click)
def setup_connections(self):
self.btn_click.clicked.connect(self.bouton_clicked)
def bouton_clicked(self):
message_box = QtWidgets.QMessageBox()
message_box.setWindowTitle("Bravo")
message_box.setText("Première application réussi")
message_box.exec_()
Finally I have create a freeze.sh file with this:
source ~/PycharmProjects/venv/Scripts/activate
cd ~/PycharmProjects/echaufement/
fbs clean
fbs freeze
I cd my src/main folder and usig: sh freeze.sh
it create a target folder containing my App.exe
but when open my App.exe I have the following error: fail to execute script main
Finally after debugging -fbs freeze --debug- and I have this - see image please
Thank you for your help.
Is there some pathing issue with ./Scripts/fbs-script.py line 11?
Also as a general rule, fbs doesn't play well beyond python 3.6. Try freezing the app again when a python 3.6.x venv?
I've outlined how to use a python 3.6.x virtualenv to build fbs app here: How to compile PyQt5 program that uses python 3.8
I am learning pyqt5 and somehow I can't use fcitx in the text box created by QTextEdit or QLineEdit although fcitx works normally with other Qt apps like goldendict or kate. But later I found out that fcitx also doesn't work with another Qt app named Retext which uses Qt 5.10. Maybe this has something to do with the latest version of Qt or so I think.
Here's my code, just a simple textbox and nothing else:
import PyQt5.QtWidgets as QtWidgets
import sys
class App(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.text = QtWidgets.QTextEdit()
self.initUI()
def initUI(self):
vbox = QtWidgets.QVBoxLayout()
vbox.addWidget(self.text)
self.setLayout(vbox)
self.show()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Thanks to #ekhumoro, I know how to fix this. Just enable input method by adding this line to the __init__ function:
self.setAttribute(Qt.WA_InputMethodEnabled)
Then do this:
cp /usr/lib/x86_64-linux-gnu/qt5/plugins/platforminputcontexts/fcitxplatforminputcontextplugin.so ~/.local/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforminputcontexts
sudo chmod +x ~/.local/lib/python3.6/site-packages/PyQt5/Qt/plugins/platforminputcontexts/fcitxplatforminputcontextplugin.so
I wrote a script (test.py) for Data Analysis. Now I'm doing a GUI in PyQt.
What I want is when I press a button 'Run', the script test.py will run and show the results (plots).
I tried subprocess.call('test1.py') and subprocess.Popen('test1.py') but it only opens the script and don't run it.
I also tried os.system, doesn't work either.
The script below is not complete (there are more buttons and functions associated but is not relevant and aren't connect to the problem described).
I'm using Python 3.6 on Spyder and PyQt5.
Is there any other function or module that can do what I want?
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("TEMP FILE")
self.home()
def home (self):
btn_run = QPushButton("Run", self)
btn_run.clicked.connect(self.execute)
self.show()
def execute(self):
subprocess.Popen('test1.py', shell=True)
subprocess.call(["python", "test1.py"])
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()
GUI = Window()
app.exec_()
What you need to do is create a text label, then pipe stdout / stderr to subprocess.PIPE:
p = subprocess.Popen(
"python test1.py",
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
Then call subprocess.Popen.communicate():
stdout, stderr = p.communicate()
# Display stdout (and possibly stderr) in a text label
You can import test1.py and call functions from within it whenever you wish
Use this How can I make one python file run another?
QProcess class is used to start external programs and to communicate with them.
Try it:
import sys
import subprocess
from PyQt5 import Qt
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton
from PyQt5.QtCore import QProcess
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
self.setGeometry(50, 50, 500, 300)
self.setWindowTitle("TEMP FILE")
self.home()
def home (self):
btn_run = QPushButton("Run", self)
#btn_run.clicked.connect(self.execute) # ---
filepath = "python test1.py" # +++
btn_run.clicked.connect(lambda checked, arg=filepath: self.execute(arg)) # +++
self.show()
def execute(self, filepath): # +++
#subprocess.Popen('test1.py', shell=True)
#subprocess.call(["python", "test1.py"])
# It works
#subprocess.run("python test1.py")
QProcess.startDetached(filepath) # +++
if not QApplication.instance():
app = QApplication(sys.argv)
else:
app = QApplication.instance()
GUI = Window()
app.exec_()
This is PyQT code that I have to be executed in Spyder. The first time, I executed it, it works well. On the second time, it says:
QWidget: Must construct a QApplication before a QPaintDevice "
I searched for solution but nothing worked for me.
from PyQt4 import QtGui, QtCore
import sys
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.button = QtGui.QPushButton('Test', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.button)
def handleButton(self):
print ('Hello World')
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.show()
app.exec_()
#sys.exit(app.exec_())
I even commented sys.exit() which some people proposed. Could someone help me to get rid of this error as I am restarting the kernel every other time to execute.
First, your example is not really minimal. You'll observe, that
from PyQt4 import QtGui
if __name__ == '__main__':
app = QtGui.QApplication([])
w = QtGui.QWidget()
w.show()
app.exec_()
already does the trick.
My guess is that the console in which you let this script run twice is not deleting the QApplication (type app in the console you see the variable is still there).
In the second run, the newly created QApplication interferes with the still existing from the old run. They all run within the same console and it depends a bit on what spyder does when running a file.
To circumvent this delete the app before another run:
del app