Pyinstaller使用笔记
主要解决打包之后运行程序闪退,图片资源无法打包的问题
安装
pip install pyinstaller
如果报’pip’ 不是内部或外部命令,也不是可运行的程序或批处理文件。
说明没有配置环境变量
右键我的电脑——属性——高级系统设置——环境变量——
用户变量对系统安全,但作用域只在本用户
系统变量作用域在整个电脑
在path变量中添加python的\python\Scripts路径,因为下面有你的pip.exe,告诉cmd去哪里找pip
如果报
WARNING: You are using pip version 19.2.3, however version 20.2.2
is available.You should consider upgrading
via the ‘python -m pip install --upgrade pip’ command.
或者
Traceback (most recent call last):
File “e:\rj\python37\lib\runpy.py”, line 193, in _run_module_as_main
“main”, mod_spec)
File “e:\rj\python37\lib\runpy.py”, line 85, in run_code
exec(code, run_globals)
File "E:\RJ\python37\Scripts\pip.exe_main.py", line 5, in
ModuleNotFoundError: No module named ‘pip’
说明pip版本过低或者损坏,更新一下
如果是line4报错,一般是pip版本和python版本不匹配,常在更新pip时出现,使用ensure匹配正确pip版本就好
python -m ensurepip
在cmd中执行
pip install --upgrade pip
pip和pyinstaller安装好了,开始使用
编译
在代码所在目录执行
pyinstaller -F namespace.py
开始打包
打包过程中报错一般是代码问题或者命令使用错误,此处不展开
解决闪退/资源文件无法引入的问题
打包结束,如果程序中引用了外部资源,打开程序后会闪退
打开编译好的.spec文件
.spec文件里面是打包时候的参数,可以再打包的时候使用命令添加的,但是我个人喜欢.spec配置,因为命令记不住
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['happyBirthdayToYou.py'],
pathex=['E:\\PythonPlay\\21\\07\\19\\HappyBirthDay\\main'],
binaries=[], # 打包动态链接库文件(so或dll)
datas=[], # 打包程序需要的数据
hiddenimports=[], # 一些难以打包进去的库放到里面
hookspath=[], # 指定hook文件夹,搜索添加库所需的所有文件
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,
[], #!!!这里是重点!!!('文件名','包括文件路径的文件名','DATA')
name='happyBirthdayToYou',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,icon='wdy.ico' )
在spec中写的代码遵循python语法,如果完成下面步骤之后还是报错请检查语法是否合法
[], #!!!这里是重点!!!(‘文件名’,‘包括文件路径的文件名’,‘DATA’) 在方括号里填外面的内容(列表里加一个元组)
配置好这里之后需要在代码中引用文件的地方加一个函数才可以打包成功
def resource_path(relative):
if hasattr(sys, "_MEIPASS"):
absolute_path = os.path.join(sys._MEIPASS, relative)
else:
absolute_path = os.path.join(relative)
return absolute_path
# 在原来引用该文件的地方加上这个函数 (resource_path("文件名"))
确保所有引用资源文件的额地方都使用了这个函数,运行无误,再次打包
注意这次打包的对象文件不再是代码,而是已经修改好的.spec文件
pyinstaller -F namespace.spec
再次运行文件,应该就没错了
关于Pyinstaller的命令和spec的设置参数具体参考官方文档