【发布时间】:2022-12-03 14:07:46
【问题描述】:
我正在通过构建与设计器的接口并导出到 .ui 文件来构建 PyQt5 应用程序。后者然后由我的主类加载。这是我的源代码示例,名称为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())
主界面
<?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.xml 位于同一文件夹中。我已经按照here的回答更改了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 文件所在的位置?
【问题讨论】:
-
如果您真的决定使用单文件捆绑的可执行文件,@RichardSmith 的答案看起来不错。我质疑单文件提议的价值,因为它保证 (1) 运行速度较慢并且 (2) 占用更多磁盘空间。可能有一个我不知道的好用例,但我通常只分发整个
dist文件夹。 -
据我所知,你至少在(1)是对的。对于
dist文件夹,我们是否应该使用“简单”loadUi('main.ui', self)加载.ui? -
是的,loadUi 应该可以在您的 EXE 文件中正常工作。我在我的大部分应用程序中使用 loadUiType。您只需要通过将 .ui 文件放入 spec 文件的 added_files 部分来确保它包含在您的 dist 文件夹中。