PyQT5 ui 文件,无法从可执行文件正确加载

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

我正在通过构建与设计器的接口并导出到 .ui 文件来构建 PyQt5 应用程序。后者然后由我的 main class 加载。这是我的源代码示例,名称为 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>

我通过给 pyinstaller -F -w main.py.

生成一个带有 pyinstaller 的可执行文件

开始时,可​​执行文件应与 ui 在同一文件夹中。我根据 .

的回答更改了 loadUI

当我现在 运行 可执行文件时,它会给我一条带有以下回溯的错误消息:

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 "PyQt5\uic\__init__.py", line 238, in loadUi
  File "PyQt5\uic\Loader\loader.py", line 66, in loadUi
  File "PyQt5\uic\uiparser.py", line 1020, in parse
  File "xml\etree\ElementTree.py", line 1202, in parse
  File "xml\etree\ElementTree.py", line 584, in parse
FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\username\AppData\Local\Temp\_MEI187162\main.ui'

发生的事情是,在 运行 .exe 文件之后,创建了一个包含一些 dll 文件的临时目录,程序试图在其中找到 .ui 文件,但没有成功.如何将可执行文件定向到 .ui 文件所在的位置?

将此添加到程序顶部的某处:

import sys
import os

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

然后当你去打电话时loadUi():

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

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

编译程序时和 运行 其他地方的目录可能会变得有点奇怪。看看这是否适合您,如果不适合,请告诉我,我可以进一步提供帮助。