我想用cx_Freeze冻结基线后在PyQt窗口中显示自定义图标。从IDE(对于我来说是Spyder)中执行取消冻结的脚本时,该图标显示正常。我正在使用PyQt5,Python 3.6和Windows10。这是我的Python脚本(IconTest.py
),它创建一个主窗口,并显示图标的路径以及该路径是否存在。图标文件必须与IconTest.py
位于同一目录:
import sys, os
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
from PyQt5.QtGui import QIcon
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(200, 300, 600, 100)
if getattr(sys, 'frozen', False): #If frozen with cx_Freeze
self.homePath = os.path.dirname(sys.executable)
else: # Otherwise, if running as a script (e.g., within Spyder)
self.homePath = os.path.dirname(__file__)
self.iconFileName = os.path.join(self.homePath, 'myIcon.ico')
self.setWindowIcon(QIcon(self.iconFileName))
self.setWindowTitle('Icon')
self.label1 = QLabel(self)
self.label2 = QLabel(self)
self.label1.move(10, 20)
self.label2.move(10, 40)
self.label1.setText("Path to icon file: " + str(self.iconFileName))
self.label2.setText("Does file exit? " + str(os.path.exists(self.iconFileName)))
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
这是从Spyder(未冻结)运行脚本时的结果。如您所见,将显示类似于秒表的图标:
这是我用于创建冻结基线的setup.py:
from cx_Freeze import setup, Executable
import os, sys
exeDir = os.path.dirname(sys.executable)
platformsPath = os.path.join(exeDir, "Library\\Plugins\\Platforms\\")
iconPath = os.path.join(os.path.dirname(__file__), "myIcon.ico")
exe=Executable(script="IconTest.py", base = "Win32GUI", icon = iconPath)
includes=[iconPath, platformsPath]
excludes=[]
packages=[]
setup(
version = "0.1",
description = "My Icon Demo",
options = {'build_exe': {'excludes':excludes,'packages':packages,'include_files':includes}},
executables = [exe]
)
这是运行冻结的脚本(build
目录中的可执行文件)时的结果。如您所见,秒表图标已替换为通用Windows图标:
建议?
答案 0 :(得分:1)
有趣的问题和很好的最小示例。经过一些搜索,我想可能与PyQt5缺少用于在冻结的应用程序中显示.ico图像文件的插件/ DLL有关。参见例如How to load .ico files in PyQt4 from network。
如果是这样,您有2个选择:
尝试将.png文件用作窗口图标的相同示例
如果冻结应用程序中包含plugins
目录,但找不到该目录,请尝试添加以下语句
pyqt_dir = os.path.dirname(PyQt5.__file__)
QApplication.addLibraryPath(os.path.join(pyqt_dir, "plugins"))`
之前
app = QApplication(sys.argv)
在您的主脚本中。参见this answer。
如果冻结的应用程序中不包含plugins
目录,则需要使用cx_Freeze
选项的include_files
条目告诉build_exe
包括它。您可以使用PyQt5
中的元组(source_path_to_plugins, destination_path_to_plugins)
动态地让设置脚本将其包含在include_files
正在查找的位置,或者您告诉PyQt5
在哪里使用QApplication.addLibraryPath
寻找它。
在对这个问题的上一个问题中,您实际上有一个条目要在安装脚本中包含一个Plugins\\Platforms
目录,也许您只需要修复此包含。请注意,与其他版本相反,cx_Freeze
版本5.1.1(当前)和5.1.0将所有软件包移动到lib
目录的build
子目录中。
答案 1 :(得分:1)
ANSWER::我一直在使用Anaconda平台,并在其他文章中读到,由于Anaconda构建其内容的方式,PyInstaller和Anaconda之间存在问题。考虑到cx_Freeze可能存在相同的问题,我在另一台计算机上安装了Python(无Anaconda),并冻结了该新Python安装中的脚本。 该图标在冻结的脚本中按预期方式显示。为了使图标正确显示,我对setup.py脚本进行了以下更改:
import sys
exeDir = ...
行platformsPath = ...
platformsPath
列表中删除了includes =
答案 2 :(得分:0)
我遇到类似的问题,并发布了答案here。
基本上,我已通过将文件存储在python字节数组中并通过QPixmap将其加载到QIcon中来解决了这个问题。