pyinstaller快速入手简单案例
pyinstaller 打包exe
pyinstaller官方文档: https://pyinstaller.org/en/stable/usage.html
博客专栏pyinstaller: https://blog.csdn.net/u012219045/category_10483280.html
关于打包;直接食用案例
https://blog.csdn.net/xqe777/article/details/124308646
https://blog.csdn.net/bigzql/article/details/110944639
https://www.jianshu.com/p/bfdbbaeeaa2f
本文打包案例基于
[tkinter] 快速入手简单案例;附源码可直接弄到本地运行;附成果物可直接下载体验
关于打包资源; 图标与背景图片处理方式
https://blog.csdn.net/sinat_27382047/article/details/81304065
https://blog.csdn.net/MemoryD/article/details/83147300
看了几篇blog,这几篇blog时间比较远了,可能是我没遇见更好的吧。
处理方式大多都是将图片资源处理编码成py文件,使用的时候在解码,自我感觉贼麻烦。
直到遇见exe运行时信息的文章时,世界就明亮了…
参考: https://www.programmersought.com/article/6945225630/
exe运行时信息
官文: https://pyinstaller.org/en/stable/runtime-information.html
基本原理
Pyinstaller可以将资源文件打包成exe。exe运行时,会生成一个临时文件夹。程序可以通过sys._MEIPASS访问临时文件夹中的资源。 (打包进来的资源文件也会在运行时生成在临时文件中)
判断程序是Python脚本生成的exe文件,还是本地的Python脚本;
当程序是Python脚本生成的exe文件,它会在sys模块中添加’frozen’属性;
当程序是本地的Python脚本,__file__属性指的是它所在模块的当前路径。
因此,打包时需要将资源文件打包进去。
exe运行的时候,会生成一个临时目录-> C:\Users\linghky\AppData\Local\Temp_MEI{6位数字}{资源文件所在处}
打包时的取舍
-F 生成结果是一个exe程序,所有第三方依赖库和其他资源都被打包进该exe程序中
-D 生成结果是一个包含exe程序的目录,所有第三方依赖库和其他资源和exe程序位于同一目录下(默认)
-D 打包出来的exe运行速度确实快, 但它与目录是一个整体, 更换目录与分享时, 存在不便之处;
-F 打包出来的exe包含着-D打包出来的目录内容, 且在运行时, 会将目录内容解压到"临时目录", 这一步操作导致-F比-D运行时慢了许多;
“临时目录”: C:\Users\linghky\AppData\Local\Temp_MEI{6位数字}
综上 如果项目比较小的话可以用-F, 但比较大的话就不推荐;
声明: 本文提到的"生成临时目录", 是在-F打包运行下创建的; -D打包的话, "临时目录"就是exe程序的所在目录;
exe运行时生成的文件目录(png是打包进去的额外资源)
打包额外资源: https://blog.csdn.net/u012219045/article/details/114841287
更新windows_app.py文件
global run_path
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
run_path = sys._MEIPASS # exe运行时临时文件夹路径(exe运行时使用绝对路径) C:\Users\linghky\AppData\Local\Temp\_MEI{6位数字}
else:
run_path = "" # (python脚本运行时使用相对路径)
# 获取运行时的路径
def func_get_run_path(relative):
return os.path.join(run_path, relative)
# 重新处理涉及到图片资源的地方
app_window.iconphoto(True, tkinter.PhotoImage(file=func_get_run_path("png/icon.png")))
background = tkinter.PhotoImage(file=func_get_run_path("png/yyh.png"))
tip = tkinter.PhotoImage(file=func_get_run_path("png/tip.png"))
脚本化打包案例 pack_windows_app.py
脚本化: https://pyinstaller.org/en/stable/usage.html#running-pyinstaller-from-python-code
# -*- coding: utf-8 -*-
"""
@auther: linghky
@date: 2023/2/8 19:26
"""
import PyInstaller.__main__ as installer
run_chose = True # True False
python_script_name = 'windows_app.py'
spec_name = 'MFNB v1.23 By kori4813.spec'
if run_chose: # True
# 参数: https://pyinstaller.org/en/stable/usage.html#options
installer.run([
python_script_name,
'--clean', # 在本次编译开始时,清空上一次编译生成的各种文件。即清空build目录里的文件。
'-y', # 如果dist文件夹内已经存在生成文件,则不询问用户直接覆盖。
'-F', # 生成one-file的程序 生成结果是一个exe文件,所有的第三方依赖、资源和代码均被打包进该exe内
'-w', # 不显示命令行窗口 编写GUI程序时使用此参数有用。
# 打包额外资源 https://blog.csdn.net/u012219045/article/details/114841287
'--add-data=png\*.png;png', # 打包额外资源到exe;
'-nMFNB v1.23 By kori4813', # -n打包名
'-i=png\yyh.ico',
# 设置图标 使用ico格式,要知道仅对 Windows 有效。
# https://blog.csdn.net/u012219045/article/details/112259317
# 进入dist的目录看下,可执行文件的图标,竟然没变。其实已经没问题了,你把这个文件夹整个拷贝到桌面,进入看一下,果然变了。
])
else: # False
# .spec文件介绍: https://blog.csdn.net/u012219045/article/details/113977724
installer.run([
spec_name # 修改生成.spec的文件后直接运行这个
])
打包前后的目录结构
补充(使用upx压缩exe文件)
参考 https://blog.csdn.net/Pekoes/article/details/124263837
python环境的Scripts文件夹内缺少了一个upx.exe的文件;
官网 https://upx.github.io/ 中下载一个UPX; 只需要其中的upx.exe;
将其复制粘贴到python环境的Scripts文件夹中即可解决该问题;