Задать вопрос

Тkinter, после сборки pyinstaller не видит файл иконки, ошибка: bitmap «icon.ico» not defined. Как исправить?

Скрипт Python, до сборки pyinstaller в один исполняемый файл – успешно работает.
В корне проекта находится файл - icon.ico
В скрипте:

root.iconbitmap(default="icon.ico")

Однако после компиляции проекта pyinstaller в один исполняемый файл, команда:

pyinstaller --name Analyzer --icon=icon.ico --add-data "icons/*;." --noconsole --onefile main.py


При запуске полученного исполняемого файла ошибка:

Traceback (most recent call last):
File "main.py", line 140, in
File "tkinter\__init__.py", line 2269, in wm_iconbitmap
_tkinter.TclError: bitmap "icon.ico" not defined


67d417f3e783c392801098.jpeg
Я так понимаю, почему-то в сборку не попадает файл иконки.

Прошу, подскажите: Чем может быть вызвана проблема? Как поправить?
  • Вопрос задан
  • 80 просмотров
Подписаться 1 Простой 2 комментария
Решения вопроса 1
@eminsk
программирую на python
Проблема в том, что когда ты компилируешь приложение в один файл (--onefile), все ресурсы упаковываются внутрь исполняемого файла и извлекаются во временную директорию во время выполнения. Путь к файлу иконки уже не соответствует тому, что был в исходном проекте.
Используй относительные пути с правильным флагом --add-data

pyinstaller --name Analyzer --icon=icon.ico --add-data "icon.ico;." --noconsole --onefile main.py


теперь твоя иконка будет добавлена в сам твой файл уже
Лично таких проблем как у тебя не было у меня.

И чтобы бы ты представлял правильность кода:
import os
import sys
import tkinter as tk
from PIL import Image, ImageTk

class AppResources:
    def __init__(self, relative_path: str):
        self.relative_path = relative_path
        self.base_path = self._get_base_path()
        self.absolute_path = self._get_absolute_path()
    
    def _get_base_path(self) -> str:
        return sys._MEIPASS if hasattr(sys, '_MEIPASS') else os.path.abspath(".")
    
    def _get_absolute_path(self) -> str:
        return os.path.join(self.base_path, self.relative_path)
    
    def load_image(self) -> ImageTk.PhotoImage:
        return ImageTk.PhotoImage(Image.open(self.absolute_path))

class App(tk.Tk):
    def __init__(self, icon_path: str):
        super().__init__()
        self.icon_path = icon_path
        self._setup_ui()
    
    def _setup_ui(self):
        self.title("Optimized Tkinter App")
        self.geometry("400x300")
        self._set_icon()
    
    def _set_icon(self):
        resources = AppResources(self.icon_path)
        icon = resources.load_image()
        self.iconphoto(True, icon)

if __name__ == "__main__":
    app = App("icon.ico")
    app.mainloop()
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы