Pyinstaller 独立可执行文件找不到规范文件中定义的 ui 文件
Posted
技术标签:
【中文标题】Pyinstaller 独立可执行文件找不到规范文件中定义的 ui 文件【英文标题】:Pyinstaller standalone executable cannot find ui file defined in spec file 【发布时间】:2020-05-19 09:03:43 【问题描述】:我正在使用 pyinstaller 编译一个独立的可执行文件。 python 脚本使用来自 QtDesigner 的外部 ui 文件。如果没有 ui 文件,我无法让它运行可执行文件。我阅读了有关定义规范文件的信息,但是如果没有 ui 文件,我尝试的一切都不起作用。我不知道我做错了什么。我可以编译它,但是当我删除 ui 文件并运行可执行文件时,我得到了错误:
FileNotFoundError: [Errno 2] No such file or directory: 'D:/visu.ui'
如何将此文件集成到可执行文件中?
这是我的代码。使用pyi-makespec生成spec文件并手动添加数据:
visu.py
import sys
import os
from PyQt5 import QtWidgets, uic
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
Ui_MainWindow, QtBaseClass = uic.loadUiType(resource_path('visu.ui'))
class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
visu.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>172</width>
<height>122</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>40</x>
<y>50</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Ok</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
visu.spec
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['D:/visu.py'],
pathex=['C:\\Users\\xxx'],
binaries=[],
datas=[("visu.ui", '.')],
hiddenimports=[],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='visu',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='visu')
【问题讨论】:
【参考方案1】:我确定如果您将visu.ui
文件转换为visu.py
pyuic5 visu.ui -o visu.py
那么你不会有任何问题。
pyinstaller -F -w pyinstaller_standalone_executable.py
pyinstaller_standalone_executable.py
import sys
import os
from PyQt5 import QtWidgets #, uic
from visu import Ui_Dialog
'''
def resource_path(relative_path):
""" Get absolute path to resource, works for dev and for PyInstaller """
try:
# PyInstaller creates a temp folder and stores path in _MEIPASS
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
Ui_MainWindow, QtBaseClass = uic.loadUiType(resource_path('visu.ui'))
'''
#class MyWindow(QtWidgets.QMainWindow, Ui_MainWindow):
class MyWindow(QtWidgets.QDialog, Ui_Dialog):
def __init__(self):
super().__init__()
self.setupUi(self)
self.pushButton.clicked.connect(
lambda: QtWidgets.QMessageBox.information(None, "Message", self.pushButton.text())
)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.show()
sys.exit(app.exec_())
【讨论】:
以上是关于Pyinstaller 独立可执行文件找不到规范文件中定义的 ui 文件的主要内容,如果未能解决你的问题,请参考以下文章
使用 Pyinstaller 时找不到隐藏的导入 Tensorflow 包
PyInstaller 包烧瓶应用程序无法加载 Python 库,dlopen -> 找不到图像
Pyinstaller - 编译应用程序后找不到 libmagic