接下来进行打包:
pyinstaller -w -F --add-data assets;assets my_app_name.py
打包完成后会生成一个包含嵌入资源的单独的exe,无需将资源文件放到同一文件夹下也能正常运行。
–add-data的参数由源文件名src和目标文件名dest组成。路径的源文件名和目标文件名用文件分隔符进行分隔,源文件名是该文件或文件夹的原本的路径,目标文件名是该文件夹嵌入到exe后的放入的文件夹名。
文件分隔符:在Windows系统上是分号,大部分unix系统上是冒号,可以通过os.pathsep来查看当前系统上的文件分隔符。例如:
>>> import os >>> os.pathsep ';'
比如–add-data "assets;assets"就表示将原本assets里面的所有文件,放入打包后的assets文件夹。再比如–add-data "assets/*.mp3;music"表示将原本assets里面的所有mp3文件,放入打包后的music文件夹。
4.5 更改图标
打包完成后,默认的程序图标是一个“蛇”形,但我们也可以进行更改。(根据官方文档,该功能只能在Windows和macOS上使用)
–icon或-i参数用于设置图标,该参数的值默认为"NONE",表示使用默认的图标;也可以指定为一个*.ico格式的Windows图标文件路径;*.icns的Mac图标文件路径;或者一个其他图片文件(需安装pillow模块,会通过pillow模块将其转换成标准的ico/icns格式)。
首先添加一个图标文件。图标文件在Windows上格式为*.ico,Mac上是*.icns。
- my_app
- assets
- image.gif
- my_app_name.py
- icon.ico
这个图标文件其实放在哪里都可以,因为打包完成后其实它也相当于嵌入了exe。但为了方便,还是把它放到同一文件夹下比较好。
pyinstaller -i icon.ico my_app_name.py
为了方便看,之前设置的-w, -F这些选项都省略了。最后生成了一个图标与icon.ico相一致的exe。
4.6 启动画面(闪屏)
pyinstaller单文件模式启动速度较慢,所以可能需要一个启动画面(闪屏)进行过渡,提示用户正在进行加载。这个启动画面可以是单张图片,也可以是文本(默认情况下文本禁用,使用方式参见第5章)。
这个启动画面的实现基于Tcl/Tk(和python tkinter模块一样),打包时会附带约1.5MB的额外文件来支持这个功能。
支持闪屏,需要先准备一张图片,必须是PNG格式(如果你安装了pillow模块,可以用pillow模块支持的其他格式)。然后,在打包时加上–splash参数,并传入图片路径。
pyinstaller --splash splash.png my_app_name.py
控制闪屏可以通过pyi_splash模块,这个模块和上一节的sys._MEIPASS属性一样,在没有通过pyinstaller打包成exe后是不起作用的,所以必须带上try…except…代码。
pyi_splash.close()方法用于关闭闪屏。一般放在程序开头即可,因为只要运行到程序开头,说明pyinstaller的加载就基本完成了。
于是,在程序开头部分添加以下代码:
try:
import pyi_splash
pyi_splash.close()
except ImportError:
pass
如果不用这段代码进行关闭,那么闪屏将一直显示。
打包后,闪屏效果如下。
至于pyi_splash还有一个update_text方法,用于在闪屏画面上显示加载文本,将在5.7节介绍。
4.7 禁用异常提示
–disable-windowed-traceback参数用于禁用异常提示。如果不添加这个参数,将会在非控制台程序出错(似乎仅限非致命的错误)时弹出一个窗口报告异常信息(注意:仅在隐藏控制台模式下弹出异常报告窗口)。为了测试,我在代码第一行添加了raise Exception,运行打包后的exe后效果如图所示。
5 使用Spec文件
当你调用以上的打包方式时,会在脚本的文件夹下生成一个*.spec文件。
*.spec文件包含了打包需要使用的所有配置信息。直接在命令行中将*.spec文件路径传给pyinstaller,也可以进行打包。比如:
pyinstaller my_app_name.spec
(其中my_app_name.spec是根据my_app_name.py生成的Spec文件)
这样,当你多次打包同一个项目时,就无需每次都传入那么多参数,只需要传入*.spec文件的路径即可。
*.spec文件也比较好处理,直接使用python编辑器或记事本就能编辑。
5.1 生成Spec文件
使用pyi-makespec工具可以根据pyinstaller的命令行参数生成Spec文件。用法很简单,在原先使用pyinstaller的打包命令中,把"pyinstaller"换成"pyi-makespec"就可以生成一个Spec文件。例如:
pyi-makespec -w -F --add-data assets;assets my_app_name.py
要更改Spec文件的生成路径,可以指定参数–specpath。
如果报错提示找不到pyi-makespec,转到最后一章:常见问题。
当你使用*.spec文件进行pyinstaller打包时,大部分的打包参数都不可用,需要预先在*.spec文件中预先设定。
pyinstaller会将*.spec里面的内容当做代码执行。单文件模式和文件夹模式的*.spec文件略有不同。
下面是一个*.spec文件(单文件模式打包)的例子。
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['my_app_name.py'],
pathex=[],
binaries=[],
datas=[('assets', 'assets')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='my_app_name',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
下面是一个文件夹模式的*.spec文件的例子:
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['my_app_name.py'],
pathex=[],
binaries=[],
datas=[('assets', 'assets')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='my_app_name',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
ent