记一次pyinstall打包遇到的问题:资源文件路径不存在('D:PythonProject/xxxxxxxxx/dist/src/add.gif': no such file or directory)
一时兴起开发了一个批量重命名文件的小工具,因为其他小伙伴也有需求,就用tkinter写了一个页面,然后分享给大家使用。
页面写好了想着使用pyinstall打包,打包步骤如下:
1. 命令行cd到项目目录中
2. pyinstaller --onefile --add-data "src/*;src/" --icon=src/icon.ico BatchRenameTool.pyw
这里简单记一下:
--onefile:打包后只会生成一个exe文件
--add-data:后面跟的是资源路径,例如使用到的图片,我是放在项目目录下的src文件夹中的
--icon:是图标资源路径
以上图片全部会打包进exe文件中
很顺利的打包成功了,然后开心的双击BatchRenameTool.exe文件,然后糟心的事情发生了!!!

这是什么鬼?图片我不是打包进去了吗咋还找不到呢?

仔细看了下报错,为什么回去找dist中的图片呢?在脚本中我是动态获取的路径,方法如下

这个方法在调试开发过程中没啥问题,但是打包后依然使用此方法就会获取错误了,因为dist就是exe可执行文件的父级目录文件夹
于是添加如下方法

该方法中 getattr(sys, 'frozen', False) 可以区分是开发环境还是打包后的环境
base_dir = sys._MEIPASS是在打包时会分配一个临时文件夹路径给exe文件。运行时会将src放在此临时目录下。执行exe时会访问此路径,如下图

接下来就把所有用到资源路径的地方全部替换成这个方法
然后重新打包,执行exe大功告成
---------------------------------------------------------------------------------------------------------------------------------
顺便记一下,下面的方法可以再打开exe文件后再任务栏也显示icon图标,感觉比原生的好看些,可以自定义图标
def _init_icon_system():
try:
ico_path = get_resource_path(os.path.join("src", "icon.ico"))
print("==================")
print(ico_path)
# Windows专属配置(解决任务栏图标问题)
if sys.platform == 'win32':
# 设置唯一应用标识(避免图标丢失)
windll.shell32.SetCurrentProcessExplicitAppUserModelID("BatchRename.Tool.1.0")
# 双重图标设置保障
root.iconbitmap(default=ico_path)
hwnd = windll.user32.GetParent(root.winfo_id())
windll.user32.SendMessageW(hwnd, 0x80, # WM_SETICON
wintypes.WPARAM(0), # ICON_SMALL
wintypes.LPARAM(windll.user32.LoadImageW(0, ico_path, 1, 0, 0, 0x10)))
# 防止图标被垃圾回收
global _icon_holder
_icon_holder = PhotoImage(file=ico_path)
root.tk.call('wm', 'iconphoto', root._w, _icon_holder)
# 其他系统处理(macOS/Linux)
else:
root.iconphoto(True, PhotoImage(file=ico_path))
except Exception as e:
print(f"Icon initialization failed: {str(e)}")
# 保留原有图标设置作为兜底方案
ico_path = get_resource_path(os.path.join("src", "icon.ico"))
root.iconbitmap(ico_path)
任务栏如下图

浙公网安备 33010602011771号