Значок главного окна не отображается при замораживании с помощью cx_Freeze - PullRequest
0 голосов
/ 17 октября 2018

Я хочу отобразить пользовательский значок в окне PyQt после замораживания базовой линии с помощью cx_Freeze.Значок отображается нормально, когда незамерзающий скрипт выполняется из среды IDE (для меня Spyder).Я использую PyQt5, Python 3.6 и Windows 10. Вот мой скрипт 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

Предложения?

Ответы [ 2 ]

0 голосов
/ 06 ноября 2018

ОТВЕТ: Я использовал платформу Anaconda и читал в других публикациях, что существуют проблемы между PyInstaller и Anaconda из-за того, как Anaconda структурирует свой контент.Думая, что та же проблема может существовать с cx_Freeze, я установил Python (без Anaconda) на другую машину и заморозил скрипт из этой новой установки Python.Значок появился, как и ожидалось, в замороженном сценарии.Чтобы значок отображался правильно, я внес следующие изменения в скрипт setup.py:

  1. Удалено import sys
  2. Удалена строка exeDir = ...
  3. Удалена строка platformsPath = ...
  4. Удалено platformsPath из списка includes =
0 голосов
/ 18 октября 2018

Интересный вопрос и хороший минимальный пример.После некоторых поисков, я думаю, это может быть связано с отсутствием в PyQt5 плагина / DLL для отображения файлов изображений .ico в замороженном приложении.См., Например, Как загрузить .ico-файлы в PyQt4 из сети .

Если это так, у вас есть 2 варианта:

  1. Попробуйте то же самоепример с файлом .png в качестве значка окна

  2. Если каталог plugins включен в замороженное приложение, но не может его найти, попробуйте добавить следующие операторы

    pyqt_dir = os.path.dirname(PyQt5.__file__)
    QApplication.addLibraryPath(os.path.join(pyqt_dir, "plugins"))`
    

    до

    app = QApplication(sys.argv)
    

    в вашем основном скрипте.См. этот ответ .

    Если каталог 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, в отличие от других версий.

...