pyinstaller 打包 Windows/MacOS 应用程序
0. 安装
pip install pyinstaller
1. 参数说明
详细参数参考官方文档: https://pyinstaller.readthedocs.io/en/stable/usage.html
参数 | 参数另外的写法 | 说明 |
---|---|---|
-F | --onefile | 产生单个的可执行文件 |
-D | --onedir | 产生一个目录(包含多个文件)作为可执行程序(默认) |
-a | --ascii | 不包含 Unicode 字符集支持(默认值:如可用则包含) |
-d | --debug | 产生debug 版本的可执行文件,debug类型可指定,详见文档 |
-w | --windowed 或--noconsolc | 指定程序运行时不显示命令行窗口(仅对 Windows/MacOS 有效) |
-c | --nowindowed 或--console | 指定使用命令行窗口运行程序(仅对 Windows/MacOS 有效) |
-i <FILE.ico or FILE.exe,ID or FILE.icns> | --icon <FILE.ico or FILE.exe,ID or FILE.icns> | 将图标应用到可执行文件(仅对 Windows/MacOS 有效) |
-o <DIR> | --out=<DIR> | 指定 spec 文件的生成目录。如果没有指定,则默认使用当前目录来生成 spec 文件 |
-p <DIR> | --path=<DIR> | 设置 Python 导入模块的路径(和设置 PYTHONPATH 环境变量的作用相似)。也可使用路径分隔符(Windows 使用分号,Linux 使用冒号)来分隔多个路径 |
-n <NAME> | --name=<NAME> | 指定项目(产生的 spec)名字。如果省略该选项,那么第一个脚本的主文件名将作为 spec 的名字 |
2. 简单实用
打包单文件无命令行exe/app
pyinstaller -F -w main.py -i icon.ico
打包成包含可执行文件的目录(无命令行)
pyinstaller -w main.py -i icon.ico
3. 包含资源文件
在spec文件中更改datas选项,如需打包资源目录./resources
datas=[('resources', 'resources')],
执行如下指令打包
pyinstaller main.spec
注意:打包单文件时不可用,须在项目中进行如下设置才能访问到资源路径,原理:单文件执行时会在系统中生成临时文件夹
# 生成资源文件目录访问路径
def resource_path(relative_path):
if getattr(sys, 'frozen', False): # 是否Bundle Resource
base_path = sys._MEIPASS
else:
base_path = os.path.abspath(".")
return os.path.join(base_path, relative_path)
此函数会检测是否使用Bundle Resource,并返回临时文件的路径或项目中的相对路径,这样可以完美兼容单文件/开发模式,不需要在打包时进行调整,具体用法如下
# 原来使用路径的写法
with open('test.txt', 'r') as f:
print(f.read())
# 兼容单文件打包的路径写法
with open(resource_path('test.txt'), 'r') as f:
print(f.read())
4. 赋予打包文件管理员权限
添加参数--uac-admin
如
pyinstaller -F -w --uac-admin main.py -i icon.ico
5. 关于打包PyQt5 QtWeb应用程序
注意,PyQt包含多个依赖文件,不建议单文件打包
在打包QtWeb应用程序时也会出现错误,需要手动调整,具体方法如下:
pyinstaller pyqtweb.py -i icon.ico
打包后在dist
文件夹下生成了包含可执行文件的目录,运行可执行文件,发现报Could not find QtWebEngineProcess.exe
错误,在可执行文件所在目录中新建文件qt.conf
内容如下:
[Paths]
Prefix = ./PyQt5/Qt
将资源文件路径指向正确位置,这时运行可执行文件已经可以正常运行了,但是,将应用程序转移到没有PyQt环境的机器时,发现窗口空白,无法正常使用,查看log可以发现,缺少资源文件,打开目录PyQt5\Qt\bin
查看qt.conf
发现有引用本地环境的资源,在没有环境的机器上是没有相应资源的,因此,我们删除目录PyQt5\Qt\bin
中的qt.conf
,通过debug.log
查看缺失的文件,发现缺少如下文件:
<Python/Anaconda环境目录>\Library\resources\icudtl.dat
<Python/Anaconda环境目录>\Library\resources\qtwebengine_resources.pak
<Python/Anaconda环境目录>\Library\resources\qtwebengine_resources_100p.pak
<Python/Anaconda环境目录>\Library\resources\qtwebengine_resources_200p.pak
将这些文件复制到PyQt5\Qt\bin
目录下,应用程序就可以脱离环境运行了