Windows10下用Poetry+PyInstaller打包时无法定位tkinter图标文件
问题:PyInstaller打包后无法找到图标文件
项目结构如下:
. │ main.spec │ poetry.lock │ pyproject.toml │ README.md │ ├───my_app │ │ pyinstaller.py │ │ __init__.py │ │ │ └───src │ │ main.py │ │ │ └───images │ icon.png │ └───dist my_app.exe
我的代码如下:
# main.py import sys import os import tkinter as tk from pathlib import Path def main() -> None: root = tk.Tk() icon_file = resolve_path('images/icon.png') root.geometry('600x200') root.columnconfigure(0, weight=1) display_info = tk.StringVar() display = tk.Entry(root, textvariable= display_info) display.grid(sticky=tk.EW) info = f'{Path(icon_file).is_file()} - {icon_file}' display_info.set(info) # root.iconphoto(False, tk.PhotoImage(file=icon_file)) root.mainloop() def resolve_path(path) -> str: if getattr(sys, 'frozen', False): return os.path.abspath(Path(sys._MEIPASS, path)) return os.path.abspath(Path(Path(__file__).parent, path)) if __name__ == '__main__': main()
直接运行脚本时输出:
True - C:\Users\fred\projects\my_app\my_app\src\images\icon.png
打包成exe运行后输出:
False - C:\Users\fred\AppData\Local\Temp\_MEI163682\images\icon.png
可见exe无法找到该文件,请问图标文件应该放在哪个位置?
解决方法
问题不在图标文件的存放位置,而是PyInstaller没有把images/icon.png打包到exe中。你的路径解析逻辑是正确的,但打包时未包含该文件,导致exe运行时_MEIPASS临时目录下不存在这个文件,自然无法找到。
你需要明确告诉PyInstaller要包含这个资源文件,有两种实现方式:
方式1:打包时用命令行参数指定
执行PyInstaller打包命令时,添加--add-data参数(Windows下用分号分隔路径,Linux/macOS用冒号):
# 基于spec文件打包 pyinstaller --add-data "my_app/src/images/icon.png;images/" main.spec # 直接基于main.py打包 pyinstaller --add-data "my_app/src/images/icon.png;images/" my_app/src/main.py
该参数的作用是:将本地的my_app/src/images/icon.png文件,在打包后放入exe临时目录的images/文件夹下,与你的resolve_path逻辑完全匹配。
方式2:修改main.spec文件
打开main.spec,找到Analysis部分,修改datas参数,添加资源文件路径:
a = Analysis( ['my_app/src/main.py'], # 其他原有参数... datas=[('my_app/src/images/icon.png', 'images')], # 其他原有参数... )
元组格式为(源文件路径, 目标文件夹名),修改完成后重新执行pyinstaller main.spec即可。
通过以上任意一种方式打包后,exe运行时_MEIPASS/images/icon.png就会存在,你的路径解析代码就能正确找到文件了。
内容的提问来源于Stack Exchange,提问作者Psionman
相关产品推荐
相关产品推荐

