PyQT5 ui file, does not load properly from the executable file

Question:

I am building a PyQt5 application by constructing the interfaces with the designer and the exporting to .ui files. The latter are then loaded by my main class. Here is an example of my source code under the name main.py:

main.py

import os.path
import PyQt5.QtWidgets as qtw
from PyQt5.uic import loadUi
import sys

class MainUI(qtw.QMainWindow):
    def __init__(self, parent=None):
        super(MainUI, self).__init__()
        self._ui_path = os.path.dirname(os.path.abspath(__file__))
        loadUi(os.path.join(self._ui_path, 'main.ui'), self)

if __name__ == "__main__":
    # Create the application
    app = qtw.QApplication(sys.argv)
    # Create and show the application's main window
    win = MainUI()
    win.show()
    sys.exit(app.exec())

main.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>320</width>
    <height>240</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>110</x>
      <y>100</y>
      <width>88</width>
      <height>27</height>
     </rect>
    </property>
    <property name="text">
     <string>ok</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>320</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

I generate an executable with pyinstaller by giving pyinstaller -F -w main.py.

In the beginning the executable should be in the same folder with the ui. I have changed loadUI following the answer here.

When I run the executable now it gives me an error message with the following traceback:

Traceback (most recent call last):
  File "main.py", line 17, in <module>
    win = MainUI()
  File "main.py", line 11, in __init__
    loadUi(os.path.join(self._ui_path, 'main.ui'), self)
  File "PyQt5uic__init__.py", line 238, in loadUi
  File "PyQt5uicLoaderloader.py", line 66, in loadUi
  File "PyQt5uicuiparser.py", line 1020, in parse
  File "xmletreeElementTree.py", line 1202, in parse
  File "xmletreeElementTree.py", line 584, in parse
FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\username\AppData\Local\Temp\_MEI187162\main.ui'

What has happened is that after running the .exe file, a temporary directory is created having some dll files, and the program tries to locate the .ui file there, without success. What can be done to direct the executable to the place where the .ui file is?

Asked By: Yannis P.

||

Answers:

Add this somewhere at the top of your program:

import sys
import os

if getattr(sys, 'frozen', False):
    RELATIVE_PATH = os.path.dirname(sys.executable)
else:
    RELATIVE_PATH = os.path.dirname(__file__)

Then when you go to call loadUi():

self._ui_path = RELATIVE_PATH + "/ui_path"  # Update this as needed

loadUi(os.path.join(self._ui_path, 'main.ui'), self)

When programs are compiled and ran elsewhere the directories can get a little weird. See if this works for you, if not, let me know and I can help out further.

Answered By: Richard

I turn back from PyQt5 version 5.15.7 to version 5.15.1 by command "pip install PyQt5==5.15.1". My problem resolved.

Answered By: Pythinker
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.