Python 使用PyInstaller打包后PySide2应用程序中出现路径错误
我正在尝试用以下结构打包PySide2测试应用程序:Python 使用PyInstaller打包后PySide2应用程序中出现路径错误,python,pyinstaller,pyside2,Python,Pyinstaller,Pyside2,我正在尝试用以下结构打包PySide2测试应用程序: . ├── main.py ├── main.spec └── wizardUI ├── 10.toolBoxBtns.ui ├── 11.toolBoxShrCt.ui ├── 12.propertyBox.ui ├── 13.printing.ui ├── 14.settings.ui ├── 15.coclusion.ui ├── 1.welcomePage.ui ├──
.
├── main.py
├── main.spec
└── wizardUI
├── 10.toolBoxBtns.ui
├── 11.toolBoxShrCt.ui
├── 12.propertyBox.ui
├── 13.printing.ui
├── 14.settings.ui
├── 15.coclusion.ui
├── 1.welcomePage.ui
├── 2.graphicsScene.ui
├── 3.graphicsSceneText.ui
├── 4.textDialog.ui
├── 5.codeDialog.ui
├── 6.graphicsSceneBox.ui
├── 7.graphicsScenePixmap.ui
├── 8.graphicsSceneShrCt.ui
├── 9.toolbox.ui
└── wizard.py
当我尝试运行可执行文件时,会出现以下错误:
FileNotFoundError:没有这样的文件或目录:'/home/artem/Desktop/testUI/dist/main/wizardUI'
这是我的wizard.py文件
从PySide2导入QtCore、QtWidgets
从PySide2.QtUiTools导入QUiLoader
导入操作系统
类tutorWizard(QtWidgets.QWizard):
“”“包含简介教程”“”
def uuu init uuu(self,parent=None):
超级(导师向导,自我)。\uuuu初始化\uuuuuu(父级)
self.setWindowTitle(“简介教程”)
pages=self.findPages()
self.initPages(页)
def findPages(自我):
ui_文件=[]
cnt=1
current_dir=os.path.dirname(os.path.realpath(uu文件_uu))
而len(ui_文件)!=15:
对于os.listdir(当前目录)中的文件:
如果文件.startswith(“{}.”格式(cnt)):
追加(os.path.join(当前目录,文件))
cnt+=1
返回用户界面文件
def初始页面(自身、文件):
加载器=QUiLoader()
对于文件中的i:
file=QtCore.QFile(str(i))
file.open(QtCore.QFile.ReadOnly)
file.reset()文件
page=loader.load(文件)
file.close()文件
self.addPage(第页)
main.py是:
从PySide2.QtWidgets导入QApplication
从wizardUI.wizard导入教程向导
导入系统
app=QApplication(sys.argv)
window=tutorWizard()
window.show()
sys.exit(app.exec_())
和.spec文件是:
#-*-模式:python;编码:utf-8-*-
分组密码=无
a=分析(['main.py'],
pathex=['/home/artem/Desktop/testUI'],
二进制文件=[],
数据=[],
HiddeInputs=['PySide2.QtXml'],
hookspath=[],
运行时挂钩=[],
不包括=[],
win\u no\u Preference\u redirects=False,
win_private_assemblies=False,
密码=分组密码,
无存档=假)
pyz=pyz(a.pure,a.zipped_数据,
密码=分组密码)
exe=exe(pyz,
a、 剧本,
[],
exclude_binaries=True,
name='main',
debug=False,
引导加载程序\u忽略\u信号=False,
strip=False,
upx=真,
控制台=真)
coll=COLLECT(exe,
a、 二进制文件,
a、 拉链,
a、 数据,
strip=False,
upx=真,
upx_exclude=[],
name='main')
a、 数据+=树('/home/artem/Desktop/testUI/wizardUI')
在不更改向导.py中的当前\u dir变量的情况下,是否有办法解决此错误?您的代码存在以下问题:
- 您将在COLLECT之后向a.datas添加
,因此它不会在编译中使用,您必须在COLLECT之前添加它树()
- 您不能再使用_文件_获取目录路径,而必须使用
- 为了使.spec可移植,我将使用变量
- 我添加了第二个参数“wizardUI”来创建带有.ui的字典,我还排除了wizard.py
├── main.py
├── main.spec
├── resource.qrc
├── resource_rc.py
└── wizardUI
├── 10.toolBoxBtns.ui
├── 11.toolBoxShrCt.ui
├── 12.propertyBox.ui
├── 13.printing.ui
├── 14.settings.ui
├── 15.coclusion.ui
├── 1.welcomePage.ui
├── 2.graphicsScene.ui
├── 3.graphicsSceneText.ui
├── 4.textDialog.ui
├── 5.codeDialog.ui
├── 6.graphicsSceneBox.ui
├── 7.graphicsScenePixmap.ui
├── 8.graphicsSceneShrCt.ui
├── 9.toolbox.ui
└── wizard.py
main.py
import os
import sys
from PySide2 import QtCore, QtWidgets, QtUiTools
# https://stackoverflow.com/a/42615559/6622587
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the pyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
current_dir = os.path.join(sys._MEIPASS, "wizardUI")
else:
current_dir = os.path.dirname(os.path.abspath(__file__))
class tutorWizard(QtWidgets.QWizard):
""" Contains introduction tutorial """
def __init__(self, parent=None):
super(tutorWizard, self).__init__(parent)
self.setWindowTitle("Introduction tutorial")
pages = self.findPages()
self.initPages(pages)
def findPages(self):
ui_files = []
cnt = 1
while len(ui_files) < 15:
for file in os.listdir(current_dir):
if file.startswith("{}.".format(cnt)):
ui_files.append(os.path.join(current_dir, file))
cnt += 1
return ui_files
def initPages(self, files):
loader = QtUiTools.QUiLoader()
for i in files:
file = QtCore.QFile(str(i))
if file.open(QtCore.QFile.ReadOnly):
page = loader.load(file)
self.addPage(page)
从PySide2.QtWidgets导入QApplication
从wizardUI.wizard导入教程向导
导入系统
如果名称=“\uuuuu main\uuuuuuuu”:
app=QApplication(sys.argv)
window=tutorWizard()
window.show()
sys.exit(app.exec_())
wizard.py
import os
import sys
from PySide2 import QtCore, QtWidgets, QtUiTools
# https://stackoverflow.com/a/42615559/6622587
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the pyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
current_dir = os.path.join(sys._MEIPASS, "wizardUI")
else:
current_dir = os.path.dirname(os.path.abspath(__file__))
class tutorWizard(QtWidgets.QWizard):
""" Contains introduction tutorial """
def __init__(self, parent=None):
super(tutorWizard, self).__init__(parent)
self.setWindowTitle("Introduction tutorial")
pages = self.findPages()
self.initPages(pages)
def findPages(self):
ui_files = []
cnt = 1
while len(ui_files) < 15:
for file in os.listdir(current_dir):
if file.startswith("{}.".format(cnt)):
ui_files.append(os.path.join(current_dir, file))
cnt += 1
return ui_files
def initPages(self, files):
loader = QtUiTools.QUiLoader()
for i in files:
file = QtCore.QFile(str(i))
if file.open(QtCore.QFile.ReadOnly):
page = loader.load(file)
self.addPage(page)
另一种选择是使用而不是数据 resource.qrc
# -*- mode: python ; coding: utf-8 -*-
# https://stackoverflow.com/a/50402636/6622587
import os
spec_root = os.path.abspath(SPECPATH)
block_cipher = None
a = Analysis(['main.py'],
pathex=[spec_root],
binaries=[],
datas=[],
hiddenimports=['PySide2.QtXml', 'packaging.specifiers', 'packaging.requirements'],
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='main',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
a.datas += Tree(os.path.join(spec_root, 'wizardUI'), 'wizardUI', excludes=["*.py"])
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='main')
wizardUI/1.welcomePage.ui
wizardUI/2.graphicscene.ui
wizardUI/3.graphicscentext.ui
wizardUI/4.textDialog.ui
wizardUI/5.codeDialog.ui
wizardUI/6.GraphicsCheckBox.ui
wizardUI/7.graphicscenepixmap.ui
wizardUI/8.graphicscenshrct.ui
wizardUI/9.toolbox.ui
wizardUI/10.toolBoxBtns.ui
wizardUI/11.toolBoxShrCt.ui
wizardUI/12.propertyBox.ui
wizardUI/13.printing.ui
wizardUI/14.settings.ui
wizardUI/15.coclusion.ui
然后使用pyside2 rcc将其转换为.py:
pyside2-rcc resource.qrc -o resource_rc.py
然后您必须修改脚本:
main.py
import os
import sys
from PySide2 import QtCore, QtWidgets, QtUiTools
# https://stackoverflow.com/a/42615559/6622587
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the pyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
current_dir = os.path.join(sys._MEIPASS, "wizardUI")
else:
current_dir = os.path.dirname(os.path.abspath(__file__))
class tutorWizard(QtWidgets.QWizard):
""" Contains introduction tutorial """
def __init__(self, parent=None):
super(tutorWizard, self).__init__(parent)
self.setWindowTitle("Introduction tutorial")
pages = self.findPages()
self.initPages(pages)
def findPages(self):
ui_files = []
cnt = 1
while len(ui_files) < 15:
for file in os.listdir(current_dir):
if file.startswith("{}.".format(cnt)):
ui_files.append(os.path.join(current_dir, file))
cnt += 1
return ui_files
def initPages(self, files):
loader = QtUiTools.QUiLoader()
for i in files:
file = QtCore.QFile(str(i))
if file.open(QtCore.QFile.ReadOnly):
page = loader.load(file)
self.addPage(page)
从PySide2.QtWidgets导入QApplication
从wizardUI.wizard导入教程向导
导入系统
导入资源
如果名称=“\uuuuu main\uuuuuuuu”:
app=QApplication(sys.argv)
window=tutorWizard()
window.show()
sys.exit(app.exec_())
wizard.py
import os
import sys
from PySide2 import QtCore, QtWidgets, QtUiTools
# https://stackoverflow.com/a/42615559/6622587
if getattr(sys, 'frozen', False):
# If the application is run as a bundle, the pyInstaller bootloader
# extends the sys module by a flag frozen=True and sets the app
# path into variable _MEIPASS'.
current_dir = os.path.join(sys._MEIPASS, "wizardUI")
else:
current_dir = os.path.dirname(os.path.abspath(__file__))
class tutorWizard(QtWidgets.QWizard):
""" Contains introduction tutorial """
def __init__(self, parent=None):
super(tutorWizard, self).__init__(parent)
self.setWindowTitle("Introduction tutorial")
pages = self.findPages()
self.initPages(pages)
def findPages(self):
ui_files = []
cnt = 1
while len(ui_files) < 15:
for file in os.listdir(current_dir):
if file.startswith("{}.".format(cnt)):
ui_files.append(os.path.join(current_dir, file))
cnt += 1
return ui_files
def initPages(self, files):
loader = QtUiTools.QUiLoader()
for i in files:
file = QtCore.QFile(str(i))
if file.open(QtCore.QFile.ReadOnly):
page = loader.load(file)
self.addPage(page)
从PySide2导入QtCore、QtWidgets、QtUiTools
类tutorWizard(QtWidgets.QWizard):
“”“包含简介教程”“”
def uuu init uuu(self,parent=None):
超级(导师向导,自我)。\uuuu初始化\uuuuuu(父级)
self.setWindowTitle(“简介教程”)
pages=self.findPages()
self.initPages(页)
def findPages(自我):
ui_文件=[]
cnt=1
而len(ui_文件)<15:
it=QtCore.QDirIterator(:/wizardUI)
而它。hasNext()
filename=it.next()
name=QtCore.QFileInfo(文件名).filename()
如果name.startswith(“{}.”格式(cnt)):
ui_files.append(文件名)
cnt+=1
返回用户界面文件
def初始页面(自身、文件):
loader=qtutools.QUiLoader()
对于文件中的i:
file=QtCore.QFile(str(i))
如果文件.open(QtCore.QFile.ReadOnly):
page=loader.load(文件)
self.addPage(第页)
最后,您的项目结构如下所示:
├── main.py
├── main.spec
├── resource.qrc
├── resource_rc.py
└── wizardUI
├── 10.toolBoxBtns.ui
├── 11.toolBoxShrCt.ui
├── 12.propertyBox.ui
├── 13.printing.ui
├── 14.settings.ui
├── 15.coclusion.ui
├── 1.welcomePage.ui
├── 2.graphicsScene.ui
├── 3.graphicsSceneText.ui
├── 4.textDialog.ui
├── 5.codeDialog.ui
├── 6.graphicsSceneBox.ui
├── 7.graphicsScenePixmap.ui
├── 8.graphicsSceneShrCt.ui
├── 9.toolbox.ui
└── wizard.py
两种解决方案都找到了这是一个路径问题 简单地说, 我们应该利用这个条件