Python中如何优化Py3.6 + PyQt5图形界面程序用pyinstaller打包生成的EXE体积过大问题
用 Py3.6 + PyQt5 写了个图形界面小工具,,用“ pyinstaller -F SVDView.py ”打包,生成的 EXE 文件 33.4M
类似的程序用 Py2.7 + PyQt4 编写、pyinstaller 打包后不到 12M
于是用“ pyinstaller SVDView.py ”将程序打包到目录下,,看了下感觉有些文件是多余的,比如 opengl32sw.dll 、libGLESv2.dll 、d3dcompiler_47.dll 、Qt5Quick.dll 、Qt4Network.dll ,,将这些文件删掉执行了下程序,,程序执行正常
将这个目录压缩了下,,不到 18M,,感觉还可以,,不过感觉文件夹里一堆文件不如“ pyinstaller -F SVDView.py ”将所有内容打包成一个 EXE 文件简洁,,
pyinstaller 有没有什么命令选项可以将修改后的目录打包成一个 EXE 文件的方法??
Python中如何优化Py3.6 + PyQt5图形界面程序用pyinstaller打包生成的EXE体积过大问题
继续删掉 Qt5Qml.dll 、_ssl.pyd 、translations 目录下的除 en 和 cs 外的其他文件,,
压缩后 14.5M ,,执行暂时正常,,
帖子内容是关于用PyInstaller打包PyQt5程序后EXE文件太大的问题。这确实是个常见痛点,尤其是PyQt5本身模块就很大。核心思路就是让PyInstaller只打包用到的部分,别把整个库都塞进去。
最直接有效的方法是在.spec文件里动手脚。创建spec文件后,在Analysis部分加入excludes和binaries参数来精减。下面是一个针对PyQt5的优化spec文件示例,你参考一下:
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['your_script.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[], # 先留空,下面会具体填
noarchive=False,
optimize=0,
)
# 1. 排除肯定用不到的PyQt5子模块(根据你的实际使用情况调整)
pyqt5_excludes = [
'PyQt5.QtWebEngine',
'PyQt5.QtWebEngineCore',
'PyQt5.QtWebEngineWidgets',
'PyQt5.QtWebChannel',
'PyQt5.QtNetwork',
'PyQt5.QtSql',
'PyQt5.QtTest',
'PyQt5.QtAxContainer',
'PyQt5.QtDesigner',
'PyQt5.QtBluetooth',
'PyQt5.QtPositioning',
'PyQt5.QtSensors',
'PyQt5.QtSerialPort',
'PyQt5.QtWinExtras',
'PyQt5.QtX11Extras',
'PyQt5.QtMacExtras',
]
a.excludes.extend(pyqt5_excludes)
# 2. 排除其他可能用不到的大型库
other_excludes = [
'numpy', # 如果没用到的话
'pandas',
'scipy',
'matplotlib',
'PIL', # 如果没用到Pillow
'tkinter',
]
a.excludes.extend(other_excludes)
# 3. 关键一步:清理PyQt5的translations和qml文件夹,它们经常被误打包
# 找到PyQt5的安装路径,通常类似下面这样
import PyQt5
pyqt5_path = PyQt5.__path__[0]
# 从binaries列表中移除translations和qml(如果它们被自动加进去了)
# 更主动的做法是,在Analysis之后,直接去a.datas里删除相关条目
import os
translations_path = os.path.join(pyqt5_path, 'translations')
qml_path = os.path.join(pyqt5_path, 'qml')
# 遍历a.datas,移除包含这些路径的条目
a.datas = [item for item in a.datas if not (translations_path in item[0] or qml_path in item[0])]
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='YourAppName',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True, # 使用UPX压缩,效果显著
upx_exclude=[],
runtime_tmpdir=None,
console=False, # 如果是GUI程序
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='your_icon.ico', # 可选
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='YourAppName',
)
使用步骤:
- 先生成初始spec文件:
pyi-makespec your_script.py - 用上面的代码替换生成的spec文件内容,并根据你的实际情况调整(比如你的脚本名、排除的模块列表)。
- 使用这个spec文件打包:
pyinstaller your_script.spec
其他几个立竿见影的招儿:
- 换用更小的替代库:如果界面不复杂,可以考虑
tkinter(内置)或PySide2/PySide6(官方说许可证更友好,有时打包后体积略小)。但如果是成熟项目,换库成本高。 - 终极方案:换打包工具:如果对体积极其敏感,可以研究下
Nuitka。它把Python编译成C,然后再编译,理论上能生成更小更快的可执行文件,但配置更复杂,打包时间也更长。
总结建议: 核心是编辑spec文件,用excludes精准排除未使用的PyQt5子模块和大型依赖,并用UPX压缩。
问一下,pycharm 开发的吗,我之前试了下 pyqt5,c 语言写的,没有智能提示感觉很难受啊。
比起那些用浏览器做界面的已经好多了
用的 sublime,,智能提示很弱,确实很痛苦,,不过还好程序简单,用的组件也不多,,
Qt 基础库那几个文件如果是在 windows 下可以用 upx 之类进行压缩,体积能减少一半,但是 platform 的 dll 不能压缩,可能会运行不了,其实没必要弄成一个 exe,使用目录的方式发布就行了,如果只是简单的小工具压缩一下基本上就在 8M 左右
压缩成一个 EXE 的话,执行的时候需要解压缩 exe,然后再执行代码,比较慢。
用目录的方法速度比较快。
启动速度也是很重要的指标,,那看来还是打包成目录比较好
会不会是 import 了顶层库,这个库巨大,但是只用了一个功能。生成 exe 的时候全给抓过去了?

