PyInstaller + UI Files - FileNotFoundError: [Errno 2] No such file or directory:
PyInstaller + UI Files - FileNotFoundError: [Errno 2] No such file or directory:
我正在尝试使用 PyInstaller 将我的 .py 脚本导出到 .exe,它依赖于使用 Qt Designer 创建的 .ui 文件。
我可以确认我的 .py 脚本在 运行 通过 PyCharm 时工作正常 - 我能够看到我用 .py 创建的 GUI。 ui 个文件。
但是,当我将 .py 脚本导出到 .exe 并启动它时,我在命令行中收到以下错误:
C:\Users\giranm>"C:\Users\giranm\PycharmProjects\PyQt Tutorial\dist\secSearch_demo.exe"
Traceback (most recent call last):
File "secSearch_demo.py", line 13, in <module>
File "site-packages\PyQt4\uic\__init__.py", line 208, in loadUiType
File "site-packages\PyQt4\uic\Compiler\compiler.py", line 140, in compileUi
File "site-packages\PyQt4\uic\uiparser.py", line 974, in parse
File "xml\etree\ElementTree.py", line 1186, in parse
File "xml\etree\ElementTree.py", line 587, in parse
FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\giranm\securitySearchForm.ui'
Failed to execute script secSearch_demo
出于某种原因,.exe 文件正在路径中查找 .ui 文件 - C:\Users\giranm\
但是,在进行了一些研究后,我被告知我需要使用 os.getcwd() 并确保我的脚本中有完整路径。即使使用下面的代码,我在尝试定位 .ui 文件时仍然遇到错误。
PyInstaller: IOError: [Errno 2] No such file or directory:
# import relevant modules etc...
cwd = os.getcwd()
securitySearchForm = os.path.join(cwd, "securitySearchForm.ui")
popboxForm = os.path.join(cwd, "popbox.ui")
Ui_MainWindow, QtBaseClass = uic.loadUiType(securitySearchForm)
Ui_PopBox, QtSubClass = uic.loadUiType(popboxForm)
# remainder of code below.
我知道可以将 .ui 文件转换为 .py 并使用 pyuic4 将它们导入主例程。但是,我将对 .ui 文件进行多次编辑
因此,我无法继续转换它们。
有没有办法解决这个问题,以便我可以创建一个独立的 .exe?
我对使用 PyQT4 和 PyInstaller 还很陌生 - 非常感谢任何帮助!
在整个周末绞尽脑汁并进一步研究 SO 之后,我设法使用 UI 文件按预期编译了独立的 .exe。
首先,我使用这个答案定义了以下函数
Bundling data files with PyInstaller (--onefile)
# Define function to import external files when using PyInstaller.
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 文件以获得所需的 类。
# Import .ui forms for the GUI using function resource_path()
securitySearchForm = resource_path("securitySearchForm.ui")
popboxForm = resource_path("popbox.ui")
Ui_MainWindow, QtBaseClass = uic.loadUiType(securitySearchForm)
Ui_PopBox, QtSubClass = uic.loadUiType(popboxForm)
然后我必须使用 Qt Designer 创建资源文件 (.qrc) 并使用此资源文件嵌入 images/icons。完成后,我使用 pyrcc4 将 .qrc 文件转换为 .py 文件,该文件将在主脚本中导入。
航站楼
C:\Users\giranm\PycharmProjects\PyQt Tutorial>pyrcc4 -py3 resources.qrc -o resources_rc.py
Python
import resources_rc
确认主要 .py 脚本正常工作后,我便使用 PyInstaller 创建了一个 .spec 文件。
航站楼
C:\Users\giranm\PycharmProjects\PyQt Tutorial>pyi-makespec --noconsole --onefile secSearch_demo.py
根据 PyInstaller 的指南,我通过修改上述 .spec 文件添加了数据文件。
https://pythonhosted.org/PyInstaller/spec-files.html#adding-data-files
最后,我使用上面的 .spec 文件编译了 .exe。
您可以简单地使用:
uic.loadUi(r'E:\Development\Python\your_ui.ui', self)
使用完整路径,并使用带有标准参数的 pyinstaller,它工作正常。 r
prefix 确保反斜杠按字面解释。
另一种方法,在 Ubuntu 20.04 上测试是将 .ui
文件添加到 spec 文件的 data
部分。首先用 pyinstaller --onefile hello.py
生成一个 spec 文件。然后更新 spec 文件和 运行 pyinstaller hello.spec
.
a = Analysis(['hello.py'],
...
datas=[('mainwindow.ui', '.')],
...
下一步是更新 Python 文件中的当前目录。为此,必须使用 os.chdir(sys._MEIPASS)
命令。在未设置 _MEIPASS 时将其包装在 try-catch 中以供开发使用。
import os
import sys
# Needed for Wayland applications
os.environ["QT_QPA_PLATFORM"] = "xcb"
# Change the current dir to the temporary one created by PyInstaller
try:
os.chdir(sys._MEIPASS)
print(sys._MEIPASS)
except:
pass
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import QFile, QIODevice
if __name__ == "__main__":
app = QApplication(sys.argv)
ui_file_name = "mainwindow.ui"
ui_file = QFile(ui_file_name)
if not ui_file.open(QIODevice.ReadOnly):
print(f"Cannot open {ui_file_name}: {ui_file.errorString()}")
sys.exit(-1)
loader = QUiLoader()
window = loader.load(ui_file)
ui_file.close()
if not window:
print(loader.errorString())
sys.exit(-1)
window.show()
sys.exit(app.exec_())
我正在尝试使用 PyInstaller 将我的 .py 脚本导出到 .exe,它依赖于使用 Qt Designer 创建的 .ui 文件。
我可以确认我的 .py 脚本在 运行 通过 PyCharm 时工作正常 - 我能够看到我用 .py 创建的 GUI。 ui 个文件。
但是,当我将 .py 脚本导出到 .exe 并启动它时,我在命令行中收到以下错误:
C:\Users\giranm>"C:\Users\giranm\PycharmProjects\PyQt Tutorial\dist\secSearch_demo.exe"
Traceback (most recent call last):
File "secSearch_demo.py", line 13, in <module>
File "site-packages\PyQt4\uic\__init__.py", line 208, in loadUiType
File "site-packages\PyQt4\uic\Compiler\compiler.py", line 140, in compileUi
File "site-packages\PyQt4\uic\uiparser.py", line 974, in parse
File "xml\etree\ElementTree.py", line 1186, in parse
File "xml\etree\ElementTree.py", line 587, in parse
FileNotFoundError: [Errno 2] No such file or directory: 'C:\Users\giranm\securitySearchForm.ui'
Failed to execute script secSearch_demo
出于某种原因,.exe 文件正在路径中查找 .ui 文件 - C:\Users\giranm\
但是,在进行了一些研究后,我被告知我需要使用 os.getcwd() 并确保我的脚本中有完整路径。即使使用下面的代码,我在尝试定位 .ui 文件时仍然遇到错误。
PyInstaller: IOError: [Errno 2] No such file or directory:
# import relevant modules etc...
cwd = os.getcwd()
securitySearchForm = os.path.join(cwd, "securitySearchForm.ui")
popboxForm = os.path.join(cwd, "popbox.ui")
Ui_MainWindow, QtBaseClass = uic.loadUiType(securitySearchForm)
Ui_PopBox, QtSubClass = uic.loadUiType(popboxForm)
# remainder of code below.
我知道可以将 .ui 文件转换为 .py 并使用 pyuic4 将它们导入主例程。但是,我将对 .ui 文件进行多次编辑 因此,我无法继续转换它们。
有没有办法解决这个问题,以便我可以创建一个独立的 .exe?
我对使用 PyQT4 和 PyInstaller 还很陌生 - 非常感谢任何帮助!
在整个周末绞尽脑汁并进一步研究 SO 之后,我设法使用 UI 文件按预期编译了独立的 .exe。
首先,我使用这个答案定义了以下函数
Bundling data files with PyInstaller (--onefile)
# Define function to import external files when using PyInstaller.
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 文件以获得所需的 类。
# Import .ui forms for the GUI using function resource_path()
securitySearchForm = resource_path("securitySearchForm.ui")
popboxForm = resource_path("popbox.ui")
Ui_MainWindow, QtBaseClass = uic.loadUiType(securitySearchForm)
Ui_PopBox, QtSubClass = uic.loadUiType(popboxForm)
然后我必须使用 Qt Designer 创建资源文件 (.qrc) 并使用此资源文件嵌入 images/icons。完成后,我使用 pyrcc4 将 .qrc 文件转换为 .py 文件,该文件将在主脚本中导入。
航站楼
C:\Users\giranm\PycharmProjects\PyQt Tutorial>pyrcc4 -py3 resources.qrc -o resources_rc.py
Python
import resources_rc
确认主要 .py 脚本正常工作后,我便使用 PyInstaller 创建了一个 .spec 文件。
航站楼
C:\Users\giranm\PycharmProjects\PyQt Tutorial>pyi-makespec --noconsole --onefile secSearch_demo.py
根据 PyInstaller 的指南,我通过修改上述 .spec 文件添加了数据文件。
https://pythonhosted.org/PyInstaller/spec-files.html#adding-data-files
最后,我使用上面的 .spec 文件编译了 .exe。
您可以简单地使用:
uic.loadUi(r'E:\Development\Python\your_ui.ui', self)
使用完整路径,并使用带有标准参数的 pyinstaller,它工作正常。 r
prefix 确保反斜杠按字面解释。
另一种方法,在 Ubuntu 20.04 上测试是将 .ui
文件添加到 spec 文件的 data
部分。首先用 pyinstaller --onefile hello.py
生成一个 spec 文件。然后更新 spec 文件和 运行 pyinstaller hello.spec
.
a = Analysis(['hello.py'],
...
datas=[('mainwindow.ui', '.')],
...
下一步是更新 Python 文件中的当前目录。为此,必须使用 os.chdir(sys._MEIPASS)
命令。在未设置 _MEIPASS 时将其包装在 try-catch 中以供开发使用。
import os
import sys
# Needed for Wayland applications
os.environ["QT_QPA_PLATFORM"] = "xcb"
# Change the current dir to the temporary one created by PyInstaller
try:
os.chdir(sys._MEIPASS)
print(sys._MEIPASS)
except:
pass
from PySide2.QtUiTools import QUiLoader
from PySide2.QtWidgets import QApplication
from PySide2.QtCore import QFile, QIODevice
if __name__ == "__main__":
app = QApplication(sys.argv)
ui_file_name = "mainwindow.ui"
ui_file = QFile(ui_file_name)
if not ui_file.open(QIODevice.ReadOnly):
print(f"Cannot open {ui_file_name}: {ui_file.errorString()}")
sys.exit(-1)
loader = QUiLoader()
window = loader.load(ui_file)
ui_file.close()
if not window:
print(loader.errorString())
sys.exit(-1)
window.show()
sys.exit(app.exec_())