用cx_Freeze冻结时不显示主窗口图标

时间:2018-10-17 17:14:35

标签: python pyqt icons pyqt5 cx-freeze

我想用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(未冻结)运行脚本时的结果。如您所见,将显示类似于秒表的图标: enter image description here

这是我用于创建冻结基线的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图标:

enter image description here

建议?

3 个答案:

答案 0 :(得分:1)

有趣的问题和很好的最小示例。经过一些搜索,我想可能与PyQt5缺少用于在冻结的应用程序中显示.ico图像文件的插件/ DLL有关。参见例如How to load .ico files in PyQt4 from network

如果是这样,您有2个选择:

  1. 尝试将.png文件用作窗口图标的相同示例

  2. 如果冻结应用程序中包含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脚本进行了以下更改:

  1. 已删除import sys
  2. 删除了exeDir = ...
  3. 删除了行platformsPath = ...
  4. platformsPath列表中删除了includes =

答案 2 :(得分:0)

我遇到类似的问题,并发布了答案here

基本上,我已通过将文件存储在python字节数组中并通过QPixmap将其加载到QIcon中来解决了这个问题。