问题描述
当我尝试使用pyinstaller创建onefile可执行文件时,所有按钮图标均被删除。 我想使用相对路径,以便.exe也可以在其他计算机上运行。 我发现了一些旧的帖子,但没有使它们起作用。
Python代码:
import sys
from PyQt5 import QtCore,QtGui,QtWidgets
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self,debugging=False):
super().__init__()
self.__setupUi()
self.__retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self)
self.show()
def __setupUi(self):
self.setobjectName('MainWindow')
self.resize(400,100)
self.centralwidget=QtWidgets.QWidget(self)
self.centralwidget.setobjectName('centralwidget')
self.verticalLayout=QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setobjectName('verticalLayout')
self.pushButton=QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setText('')
icon=QtGui.QIcon()
icon.addpixmap(QtGui.Qpixmap('Icons/test.png'),QtGui.QIcon.normal,QtGui.QIcon.Off)
self.pushButton.setIcon(icon)
self.pushButton.setIconSize(QtCore.QSize(32,32))
self.pushButton.setobjectName('pushButton')
self.verticalLayout.addWidget(self.pushButton)
self.setCentralWidget(self.centralwidget)
def __retranslateUi(self):
_translate=QtCore.QCoreApplication.translate
self.setwindowTitle(_translate('MainWindow','MainWindow'))
if __name__=='__main__':
app=QtWidgets.QApplication(sys.argv)
uiObj=Ui_MainWindow()
sys.exit(app.exec())
PyInstaller命令:
python -m PyInstaller --onefile --windowed --add-data Icons/*.png;Icons test.py
.spec内容:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['test.py'],pathex=['C:\\Users\\User\\Desktop\\Neuer Ordner'],binaries=[],datas=[('Icons/*.png','Icons')],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,a.binaries,a.zipfiles,a.datas,[],name='test',debug=False,bootloader_ignore_signals=False,strip=False,upx=True,upx_exclude=[],runtime_tmpdir=None,console=False )
那该如何解决呢? 谢谢。
解决方法
所以今天我找到了解决方案。这篇旧文章(link)确实很有帮助。 我的文件夹结构例如:
Folder
- test.py
- absolutePath.py
- Icons
需要脚本absolutePath.py来生成PNG的绝对路径。文件夹图标包含PNG文件。
absolutePath.py:
import sys
import os
def absolutePath(relative_path):
base_path=getattr(sys,'_MEIPASS',os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path,relative_path)
test.py:
import sys
from PyQt5 import QtCore,QtGui,QtWidgets
from absolutePath import absolutePath
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self,debugging=False):
super().__init__()
self.__setupUi()
self.__retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self)
self.show()
def __setupUi(self):
self.setObjectName('MainWindow')
self.resize(400,100)
self.centralwidget=QtWidgets.QWidget(self)
self.centralwidget.setObjectName('centralwidget')
self.verticalLayout=QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName('verticalLayout')
self.pushButton=QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setText('')
icon=QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(absolutePath('Icons/icon.png')),QtGui.QIcon.Normal,QtGui.QIcon.Off)
self.pushButton.setIcon(icon)
self.pushButton.setIconSize(QtCore.QSize(32,32))
self.pushButton.setObjectName('pushButton')
self.verticalLayout.addWidget(self.pushButton)
self.setCentralWidget(self.centralwidget)
def __retranslateUi(self):
_translate=QtCore.QCoreApplication.translate
self.setWindowTitle(_translate('MainWindow','MainWindow'))
if __name__=='__main__':
app=QtWidgets.QApplication(sys.argv)
uiObj=Ui_MainWindow()
sys.exit(app.exec())
最后是PyInstaller命令:
python -m PyInstaller --onefile --windowed --add-data Icons\\*.png;Icons\\ test.py
如此生成的可执行文件包括文件夹中图标中的所有PNG 称为图标。这些图片可以在运行时找到并出现。该可执行文件也可以在其他计算机上使用。