python打包资源文件(图片等)的方法
一、基本步骤
(一)先使用pyinstaller命令对主程序进行打包
如果没有pyinstaller命令,先进行下载:pip install pyinstaller
打包的两种方式:
pyinstaller -D test.py # 生成一个文件夹,里面是多文件模式,启动快。
pyinstaller -F test.py # 仅仅生成一个文件,不暴露其他信息,启动较慢。
Pyinstaller -F setup.py 打包exe
Pyinstaller -F -w setup.py 不带控制台的打包
Pyinstaller -F -i xx.ico setup.py 打包指定exe图标打包
(二)修改spec文件,添加资源
1.修改datas项
datas=[('res/bg.jpg', 'res'), ('exam.db', '.')]
列表里面是元组,左边是你要添加的filename(相对路径即可),右边是拷贝到项目中之后的文件夹名字。
比如:
(‘res/bg.jpg’, ‘res’) 中的 ‘res/bg.jpg’ 表示工程根目录下res文件夹下有bg.jpg图片,拷贝到项目之后的res文件夹。
(‘exam.db’, ‘.’) 中的’exam.db’是工程根目录下的文件,’.'表示根目录,即拷贝到项目中的根目录下。
2.修改pathex项
pathex=['/Users/wenlong/exam_demo']
即添加项目地址
(三)重新编译
注意只需编译spec文件
pyinstaller test.spec
二、注意事项
(一)修改代码中资源访问路径
# 生成资源文件目录访问路径 def resource_path(relative_path): if getattr(sys, 'frozen', False): # 判断sys中是否存在frozen变量,即是否是打包程序 base_path = sys._MEIPASS # sys._MEIPASS在一些编辑器中会报错,不用理会 else: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path)run_path = resource_path(relative_path)
(二)编译spec文件时不要再加参数(-D,-F等),否则会出错
三、工作原理
(一)基本原理
Pyinstaller 可以将资源文件一起bundle到exe中,当exe在运行时,会生成一个临时文件夹,程序可通过sys._MEIPASS访问临时文件夹中的资源
官方说明:https://pythonhosted.org/PyInstaller/spec-files.html#spec-file-operation
(二)资源路径
程序打包成exe的时,会将一个变量frozen注入到sys中,这里使用判断,检测sys是否有frozen这个变量,如果有,就使用sys._MEIPASS访问临时文件夹路径,如果没有,就使用当前路径,当程序不管是以PyInstaller打包后形式运行,还是本地测试,都能找到正确的资源路径。
这个 sys._MEIPASS 是个特殊的值,是在Pyinstaller打包的时候才会添加的临时变量,通过这个变量我们可以获取到在执行exe时候的临时目录。
四、其它注意事项
WIN和MAC建议这样打包:有多个依赖包必须放在相同文件夹下,
命令:pyinstaller -F 主文件.py -p 副1.py -p 副2.py -w --icon="图标.icns"
注意:
1>如果用ttkthemes主题库,pyinstaller必须添加--hidden-import ttkthemes或者手动添加,然后单独执行pyinstaller xxx.spec;
2>Mac下要向想图标生效,只能Pyinstaller -F -w 主程序.py -i 图标.icns (必须是icns格式目前只知道这样)