Error loading PyQt5 UI file - python

I am using following code to load a ui file, but keep seeing an error message.
# main.py
import sys
from PyQt5.QtWidgets import *
from PyQt5 import uic
form_class = uic.loadUiType("main_window.ui")[0]
class MyWindow(QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()
Error message:
FileNotFoundError: [Errno 2] No such file or directory: 'main_window.ui'
main_window.ui is located in the same folder as main.py

The name of the file you pass to loadUiType is relative to the working directory, not your python file. You can pass the full path instead. To get the full path, you can find the directory of your current file and then join that with the name of your UI file.
e.g:
...
ui_path = os.path.dirname(os.path.abspath(__file__))
form_class = uic.loadUiType(os.path.join(ui_path, "main_window.ui"))[0]
...

Related

PySide6 + Qt Creator, pysideplugin error results in gray screen

Every time I create a Window UI - Dynamic load project in Qt Creator v8.0.2 and run the project I get the following error:
error: qt.pysideplugin: Environment variable PYSIDE_DESIGNER_PLUGINS
is not set, bailing out.
As a result, the window doesn't display any widgets, it is just a gray empty window
I have tried to configure os.environ['PYSIDE_DESIGNER_PLUGINS'] = '.' but then I get the following error:
error: qt.pysideplugin: No python files found in '.'.
Is there a way to load the pysideplugin to Qt Creator v8.0.2 or to remove the errors related to it and make the project run and show the widgets?
I am testing with a very simple UI
But when I run the project I can only see the following:
The complete code in the mainwindow.py file is:
# This Python file uses the following encoding: utf-8
import os
from pathlib import Path
import sys
from PySide6.QtWidgets import QApplication, QMainWindow
from PySide6.QtCore import QFile
from PySide6.QtUiTools import QUiLoader
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.load_ui()
def load_ui(self):
loader = QUiLoader()
path = Path(__file__).resolve().parent / "form.ui"
ui_file = QFile(path)
ui_file.open(QFile.ReadOnly)
loader.load(ui_file, self)
ui_file.close()
if __name__ == "__main__":
#os.environ['PYSIDE_DESIGNER_PLUGINS']='.'
app = QApplication(sys.argv)
widget = MainWindow()
widget.show()
sys.exit(app.exec())
I am using python 3.10.5 and PySide6 version 6.4.0.1

PyQt5 to PySide2, loading UI-Files in different classes

I have a python application which runs under python3.6 and is using PyQt5 for loading Ui windows. These windows were created with Qt Designer 5.9.4. The Code below shows a working example with PyQt5.
Now i want to have exactly the same functionality but with PySide2. For now, I couldn't work out how to load an Ui File and use its objects (buttons, tables etc.) in a separate class. For example: by clicking a button in the first window/class, a second window apears which functions are defined in a separate class, see example. All examples that I found, just load an Ui-Window but don't show how to work with it. Can anyone help?
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from PyQt5.uic import loadUiType
from PyQt5 import QtGui, QtCore
Ui_FirstWindow, QFirstWindow = loadUiType('first_window.ui')
Ui_SecondWindow, QSecondWindow = loadUiType('second_window.ui')
class First(Ui_FirstWindow, QFirstWindow):
def __init__(self):
super(First, self).__init__()
self.setupUi(self)
self.button.clicked.connect(self.show_second_window)
def show_second_window(self):
self.Second = Second()
self.Second.show()
class Second(Ui_SecondWindow, QSecondWindow):
def __init__(self):
super(Second, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())
PySide does not offer these methods, but one solution is to modify the source code of the PyQt uic module by changing the imports from PyQt5 to PySide2, for legal terms do not modify the license, in addition to the code that will keep the PyQt licenses.
To do this, download the source code from the following link and unzip it.
And execute the following script:
convert_pyqt5_to_pyside2.py
import os
import fileinput
import argparse
import shutil
def modify_source_code(directory, text_to_search, replacement_text):
for path, subdirs, files in os.walk(directory):
for name in files:
filename = os.path.join(path, name)
with fileinput.FileInput(filename, inplace=True) as file:
for line in file:
if line.startswith('#'):
# not change on comments
print(line, end='')
else:
print(line.replace(text_to_search, replacement_text), end='')
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-i", "--input", help="Input directory")
parser.add_argument("-o", "--output", help="Output directory")
args = parser.parse_args()
if args.input and args.output:
input_dir = os.path.join(os.path.abspath(args.input), "pyuic", "uic")
output_dir = os.path.abspath(args.output)
shutil.copytree(input_dir, output_dir)
modify_source_code(output_dir, 'PyQt5', 'PySide2')
if __name__ == '__main__':
main()
Using the following command:
python convert_pyqt5_to_pyside2.py -i /path/of/PyQt5-folder -o fakeuic
Then you can use the loadUiType method from fakeuic:
from fakeuic import loadUiType
from PySide2 import QtCore, QtGui, QtWidgets
Ui_FirstWindow, QFirstWindow = loadUiType('first_window.ui')
Ui_SecondWindow, QSecondWindow = loadUiType('second_window.ui')
class First(QFirstWindow, Ui_FirstWindow):
def __init__(self):
super(First, self).__init__()
self.setupUi(self)
self.button.clicked.connect(self.show_second_window)
def show_second_window(self):
self.Second = Second()
self.Second.show()
class Second(QSecondWindow, Ui_SecondWindow):
def __init__(self):
super(Second, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
main = First()
main.show()
sys.exit(app.exec_())
You can find the complete example here
PySide2 brought back loadUiType in May 2020. So if you upgrade, you can get a drop-in replacement. The only difference is the import:
from PySide2.QtUiTools import loadUiType
Syntax is the same (you will use loadUiType(<file>)[0] )
Follow these simple steps:
Assuming the ui file from qt designer is mycode.ui, convert this to the py file using the pyside2 ui converter by typing "pyside2-uic mycode.ui -o mycode.py" without the quotes. (Note use the pyside2 converter of pyside2-uic and not pyqt5 converter of pyuic5)
With mycode.py generated by pyside2 format, just replace all the headers for the PyQt5 code to "import sys" and "from mycode import *"
You are done...Hope this helps

Why python not show in path icon?

I wrote below code
import sys,time
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
app = QApplication(sys.argv)
sys.path.append(r"C:\Users\hpaalm\Desktop")
a=QPushButton()
a.setIcon(QIcon('1.png'))
a.show()
app.exec_()
when i run it in IDE, it show my icon, but when run it in CMD it not show icon. what is problem?
python C:\Users\hpaalm\Desktop\a.py
sys.path contains a list of paths where python imports the modules, this does not serve to import files, icons or similar resources. Instead it is best to create a function that binds the directory path with the filename and return the full path of the icon:
import os
import sys
from PyQt5 import QtGui, QtWidgets
ICON_DIR = r"C:\Users\hpaalm\Desktop"
def get_path_icon(filename):
return os.path.join(ICON_DIR, filename)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
a = QtWidgets.QPushButton()
a.setIcon(QtGui.QIcon(get_path_icon('1.png')))
a.show()
sys.exit(app.exec_())

Attribute Error: module attribute not found in defined class

I am trying to make simple Gui using pyqt and qtdesigner in Anaconda python 2.7.
I am calling a method from inside __init__ function. It returns attribute not found error.
Here is my code:
import sys, os
from PyQt5 import QtCore, QtGui, uic, QtWidgets
from awesim.pymosim import set_pars
dir_path = os.path.dirname(os.path.realpath(__file__))
qtCreatorFile = os.path.join(dir_path , 'SimpleDymolaRun.ui' )
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent = None, name = None):
QtWidgets.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.updateParameters.clicked.connect(self.Update)
def Update(self):
dir_path = os.path.dirname(os.path.realpath(__file__))
dsin = os.path.join(dir_path, 'dsin.txt')
value_dict = {'a':1, 'b':2}
set_pars(value_dict, dsin = os.path.join(dir_path, dsin.txt))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
I get following error:-
Traceback:
window = Myapp()
in __init__
self.updateParameters.clicked.connect(self.Update)
AttributeError : 'MyApp' object has no attribute 'Update'
Am I missing something crucial in definition of init. I tried suggestions in some other answers on SO, but solution mentioned therein did not work for me.
What is it that I am doing wrong?

Unable to acesse QWidget in UI file, PySide

AttributeError: 'PySide.QtGui.QWidget' object has no attribute 'test_button'
I get this error when run the following code
test.py.
from PySide import QtGui, QtCore, QtUiTools
module_dir = os.path.dirname('__file__')
ui_file_path = module_dir + '/test.ui'
def call_ui():
loader = QtUiTools.QUiLoader()
ui_file = QtCore.QFile(ui_file_path)
ui_file.open(QtCore.QFile.ReadOnly)
ui = loader.load(ui_file)
ui_file.close()
return ui
class TestUI(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.ui = call_ui()
self.setCentralWidget(self.ui)
self.ui.test_button.clicked.connected(self.test)
def test(self):
print "Testing....."
def main():
app = QtGui.QApplication(sys.argv)
win = TestUI()
win.show()
main()
test.ui file has a push button called test_button
You can't construct path of UI file in this way:
os.path.dirname('__file__')
will always return empty string, and ui_file_path will be '/test.ui'.
Correct way:
module_dir = os.path.dirname(__file__)
ui_file_path = os.path.join(module_dir, 'test.ui')
But when QUiLoader.load failed, it raises RuntimeError (tested on PySide 1.2.1). Is there a ui file on your root file system?

Categories