Python使用PyInstaller打包exe时解决图标缺失与模块未找到的问题
本文详解Python使用PyInstaller打包exe时常见的“Failed to execute script”及图标加载失败问题。通过终端运行exe查看日志定位原因,解决依赖包缺失及虚拟环境配置问题,并提供将图标嵌入代码并动态生成临时文件的方案,确保打包后的单文件exe能正确加载自定义图标。
PyInstaller打包常见问题概述
前言
鉴于近期重新梳理了Python的打包流程,今日计划对之前开发的PDF合并工具进行整理并生成可执行文件。
打包过程中再次遇到若干障碍。回顾半年前处理类似打包任务时的经验,如今对解决这些问题的思路已更为清晰,特此记录以备查阅。
运行时错误排查与依赖处理
问题
打包虽成功,但运行时出现Failed to execute script xxx错误。此错误可能由多种原因导致,此时应避免使用-w参数进行打包,改为在终端中通过.\xxx.exe方式运行程序,以便查看详细的输出日志。
原因一
D:\02-python\2019-09-30_pdf_opt\dist>.\pdfmerge.exe Traceback (most recent call last): File "pdfmerge.py", line 5, in <module> ModuleNotFoundError: No module named 'PyPDF2' [47572] Failed to execute script pdfmerge
该问题源于打包时使用了系统的pyinstaller命令,而系统Python环境中未安装所需的依赖包。解决方法有两种:一是退出当前的虚拟环境,直接使用系统Python;二是保持进入虚拟环境,并在虚拟环境的Scripts目录下安装pyinstaller命令后再进行打包。
图标加载失败的解决方案
原因二
D:\02-python\2019-09-30_pdf_opt\dist>.\pdfmerge.exe Traceback (most recent call last): File "pdfmerge.py", line 97, in <module> File "tkinter\__init__.py", line 1871, in wm_iconbitmap _tkinter.TclError: bitmap ".\assert\efon.ico" not defined [95216] Failed to execute script pdfmerge
此错误是因为在Python代码中指定了程序图标,但pyinstaller无法将外部依赖文件(如图标文件)直接打包进单个exe中。因此,需要将图标文件手动拷贝至exe所在的目录。另一种更优的解决方案是下文将介绍的将图标数据嵌入代码的方法。
将图标打包到代码中,首先需要编写一个Python程序来自动生成包含图标数据的类。
嵌入图标的实现原理
import base64
with open("icon.py","w") as f:
f.write('class Icon(object):\n')
f.write('\tdef __init__(self):\n')
f.write("\t\tself.img='")
with open("icon.ico","rb") as i:
b64str = base64.b64encode(i.read())
with open("icon.py","ab+") as f:
f.write(b64str)
with open("icon.py","a") as f:
f.write("'")
执行该生成程序后,结果如下所示:

随后,在需要打包的Python程序中指定使用该图标:
with open('tmp.ico','wb') as tmp:
tmp.write(base64.b64decode(Icon().img))
window.iconbitmap('tmp.ico')
os.remove('tmp.ico')
其原理是:首先读取Icon类中存储的ico数据,将其转换为二进制格式,写入当前目录生成一个临时ico文件,接着指定程序使用该临时图标,最后删除该临时图标。
通过这种方式,可以确保程序在当前目录下成功加载图标。整个过程一气呵成,速度极快,用户不会察觉到临时文件的生成过程。
若程序中还有其他外部依赖文件,可参照此原理进行类似处理。
至此,打包过程全部完成,最终生成单个exe文件,即可进行发布。
总结
以上介绍了Python中使用PyInstaller打包时遇到的图标问题及解决方法,希望能对大家有所帮助。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









