Python中使用PyInstaller打包PyQt5程序,打开就崩溃怎么办?
开发环境
Mac 10.13 brew 安装的 python3.6、pyqt5、 pyinstaller 3.3
开发工具
PyCharm 2016.3.3
Build #PY-163.15188.4, built on March 11, 2017
JRE: 1.8.0_112-release-408-b6 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
直接运行 python3 main.py 没有问题,各项功能均正常

打包命令
$sudo pyinstaller -w -y --onefile main.py
366 INFO: PyInstaller: 3.3
366 INFO: Python: 3.6.2
380 INFO: Platform: Darwin-17.0.0-x86_64-i386-64bit
381 INFO: wrote /Users/goodryb/PycharmProjects/aliyunUI/src/main.spec
394 INFO: UPX is available.
397 INFO: Extending PYTHONPATH with paths
['/Users/goodryb/PycharmProjects/aliyunUI/src',
'/Users/goodryb/PycharmProjects/aliyunUI/src']
397 INFO: checking Analysis
397 INFO: Building Analysis because out00-Analysis.toc is non existent
397 INFO: Initializing module dependency graph...
400 INFO: Initializing module graph hooks...
404 INFO: Analyzing base_library.zip ...
6016 INFO: running Analysis out00-Analysis.toc
6033 INFO: Caching module hooks...
6042 INFO: Analyzing /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
6545 INFO: Processing pre-safe import module hook urllib3.packages.six.moves
9180 INFO: Loading module hooks...
9180 INFO: Loading module hook "hook-requests.py"...
9183 INFO: Loading module hook "hook-PyQt5.py"...
9334 INFO: Loading module hook "hook-xml.etree.cElementTree.py"...
9336 INFO: Loading module hook "hook-encodings.py"...
9453 INFO: Loading module hook "hook-PyQt5.Qt.py"...
9464 INFO: Loading module hook "hook-certifi.py"...
9467 INFO: Loading module hook "hook-PyQt5.QtWidgets.py"...
9468 INFO: Loading module hook "hook-xml.py"...
9555 INFO: Loading module hook "hook-pydoc.py"...
9556 INFO: Loading module hook "hook-PyQt5.QtCore.py"...
9710 INFO: Loading module hook "hook-PyQt5.QtGui.py"...
10417 INFO: Loading module hook "hook-PyQt5.QtPrintSupport.py"...
10574 INFO: Looking for ctypes DLLs
10594 INFO: Analyzing run-time hooks ...
10601 INFO: Including run-time hook 'pyi_rth_qt5.py'
10613 INFO: Looking for dynamic libraries
11090 INFO: Looking for eggs
11090 INFO: Using Python library /usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/Python
11095 INFO: Warnings written to /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/warnmain.txt
11155 INFO: Graph cross-reference written to /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/xref-main.html
11182 INFO: checking PYZ
11182 INFO: Building PYZ because out00-PYZ.toc is non existent
11183 INFO: Building PYZ (ZlibArchive) /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/out00-PYZ.pyz
11947 INFO: Building PYZ (ZlibArchive) /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/out00-PYZ.pyz completed successfully.
11964 INFO: checking PKG
11964 INFO: Building PKG because out00-PKG.toc is non existent
11964 INFO: Building PKG (CArchive) out00-PKG.pkg
23536 INFO: Building PKG (CArchive) out00-PKG.pkg completed successfully.
23543 INFO: Bootloader /usr/local/lib/python3.6/site-packages/PyInstaller/bootloader/Darwin-64bit/runw
23543 INFO: checking EXE
23543 INFO: Building EXE because out00-EXE.toc is non existent
23543 INFO: Building EXE from out00-EXE.toc
23544 INFO: Appending archive to EXE /Users/goodryb/PycharmProjects/aliyunUI/src/dist/main
23635 INFO: Fixing EXE for code signing /Users/goodryb/PycharmProjects/aliyunUI/src/dist/main
23656 INFO: Building EXE from out00-EXE.toc completed successfully.
23662 INFO: checking BUNDLE
23662 INFO: Building BUNDLE because out00-BUNDLE.toc is non existent
23662 INFO: Building BUNDLE out00-BUNDLE.toc
23716 INFO: moving BUNDLE data files to Resource directory
告警信息 11095 INFO: Warnings written to /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/warnmain.txt
$cat warnmain.txt
missing module named nt - imported by os, ntpath, shutil, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named org - imported by pickle, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
excluded module named _frozen_importlib - imported by importlib, importlib.abc, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named _frozen_importlib_external - imported by importlib._bootstrap, importlib, importlib.abc, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named _winreg - imported by platform, requests.utils, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named java - imported by platform, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named 'java.lang' - imported by platform, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py, xml.sax._exceptions
missing module named vms_lib - imported by platform, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named winreg - imported by platform, mimetypes, urllib.request, requests.utils, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named urllib.proxy_bypass - imported by urllib, requests.compat
missing module named urllib.unquote_plus - imported by urllib, requests.compat
missing module named urllib.proxy_bypass_environment - imported by urllib, requests.compat
missing module named urllib.getproxies - imported by urllib, requests.compat
missing module named urllib.quote_plus - imported by urllib, requests.compat
missing module named urllib.urlencode - imported by urllib, requests.compat
missing module named urllib.getproxies_environment - imported by urllib, requests.compat
missing module named urllib.unquote - imported by urllib, oss2.compat, requests.compat
missing module named urllib.quote - imported by urllib, oss2.compat, requests.compat
missing module named msvcrt - imported by subprocess, getpass, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named _winapi - imported by subprocess, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named _dummy_threading - imported by dummy_threading, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
missing module named 'org.python' - imported by copy, /Users/goodryb/PycharmProjects/aliyunUI/src/main.py, xml.sax
missing module named StringIO - imported by urllib3.packages.six, requests.compat, qiniu.compat
missing module named urlparse - imported by oss2.compat, requests.compat, qiniu.compat
missing module named simplejson - imported by oss2.compat, requests.compat, qiniu.compat
missing module named urllib2 - imported by requests.compat, qiniu.services.cdn.manager
runtime module named urllib3.packages.six.moves - imported by http.client, urllib3.connectionpool, urllib3.util.response, 'urllib3.packages.six.moves.urllib', urllib3.response
missing module named backports - imported by urllib3.packages.ssl_match_hostname
missing module named _abcoll - imported by urllib3.packages.ordered_dict
missing module named dummy_thread - imported by urllib3.packages.ordered_dict
missing module named thread - imported by urllib3.packages.ordered_dict
missing module named "'urllib3.packages.six.moves.urllib'.parse" - imported by urllib3.request, urllib3.poolmanager
missing module named netbios - imported by uuid
missing module named win32wnet - imported by uuid
missing module named Queue - imported by urllib3.connectionpool, oss2.task_queue
missing module named Cookie - imported by requests.compat
missing module named cookielib - imported by requests.compat
missing module named socks - imported by urllib3.contrib.socks
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl
missing module named 'cryptography.x509' - imported by urllib3.contrib.pyopenssl
missing module named six - imported by urllib3.contrib.pyopenssl
missing module named 'cryptography.hazmat' - imported by urllib3.contrib.pyopenssl
missing module named cryptography - imported by urllib3.contrib.pyopenssl
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl
missing module named predefined - imported by crcmod
Python中使用PyInstaller打包PyQt5程序,打开就崩溃怎么办?
去年我也是这样,然后放弃了
遇到PyInstaller打包PyQt5程序后崩溃的问题,通常是因为打包时没有正确包含Qt的动态链接库和依赖资源。核心解决思路是确保所有必要的文件都被正确打包进最终的可执行文件中。
最常见的原因是缺少Qt平台的插件文件(比如 platforms/qwindows.dll)。PyInstaller默认可能不会自动收集这些运行时依赖。
解决方案:
你需要创建一个自定义的 .spec 文件来明确告诉PyInstaller包含这些关键文件。下面是一个针对PyQt5的、经过验证的 .spec 文件模板。假设你的主程序入口文件是 main.py。
-
首先生成默认的
.spec文件(如果你还没有):pyi-makespec main.py这会生成一个
main.spec文件。 -
编辑
main.spec文件,修改Analysis和EXE部分,关键是要添加collect_data_files和手动包含插件目录。以下是修改后的示例:# -*- mode: python ; coding: utf-8 -*- block_cipher = None # 1. 导入必要的PyInstaller工具函数 from PyInstaller.utils.hooks import collect_data_files, collect_submodules import os # 2. 收集PyQt5的所有数据文件(包括翻译文件、Qt插件等) pyqt5_datas = collect_data_files('PyQt5', includes=['**/*.dll', '**/*.so', '**/*.dylib', '**/qt.conf', '**/*.qm']) # 3. 如果你还用了Qt的其他模块(如图表、WebEngine),也需要显式包含 # hiddenimports = collect_submodules('PyQt5') a = Analysis( ['main.py'], pathex=[], binaries=[], # 4. 将收集到的PyQt5数据文件添加到datas中 datas=pyqt5_datas, hiddenimports=[], # 可以在这里添加隐藏导入,例如:hiddenimports += collect_submodules('PyQt5.QtWebEngineWidgets') 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='main', # 你的程序名 debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=False, # 如果是GUI程序,设为False disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, icon='your_icon.ico', # 可选:你的图标路径 ) -
使用修改后的
.spec文件进行打包:pyinstaller main.spec
如果上述方法仍不奏效,可以尝试更直接的手动方法:
在你的主程序 main.py 的最开头(在所有PyQt5导入之前),添加以下代码来强制设置Qt插件路径。这能确保程序在打包后运行时,知道去哪里找 platforms 插件。
import sys
import os
# 判断是否是打包后的可执行文件
if getattr(sys, 'frozen', False):
# 如果是打包后的程序,设置插件路径为可执行文件所在目录下的 ‘platforms’
base_dir = sys._MEIPASS
else:
# 如果是开发环境,使用默认路径
base_dir = os.path.dirname(os.path.abspath(__file__))
# 将Qt插件路径添加到环境变量中
plugins_path = os.path.join(base_dir, 'PyQt5', 'Qt5', 'plugins')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugins_path
# 然后再导入PyQt5模块
from PyQt5.QtWidgets import *
# ... 你的其他导入和代码
然后,你需要在 .spec 文件的 datas 部分,手动确保 platforms 文件夹被正确复制。你可以通过修改 datas 列表来实现,但这通常在上面 collect_data_files 方法中已经覆盖。如果问题依旧,可以显式添加:
# 在 a = Analysis 的 datas 参数里添加
datas = pyqt5_datas + [('C:/Path/To/Your/VirtualEnv/Lib/site-packages/PyQt5/Qt5/plugins/platforms', 'PyQt5/Qt5/plugins/platforms')],
注意将路径替换成你实际环境中 qwindows.dll 所在的完整路径。
总结: 问题的根源几乎总是运行时依赖缺失,通过修改 .spec 文件确保完整包含Qt库文件是根本解决方法。
#1 哎!~~,不容易呀,看来只能用脚本跑了
把 console 打开,看报错是啥
我试过 ico 打包进去会有问题
令人奔溃的奔溃信息没有啊, 试试用–onedir 打包看有错没得, 再加上–debug 打包看看能不能得到错误信息.
https://pyinstaller.readthedocs.io/en/stable/when-things-go-wrong.html
以前也折腾过, 在 windows 上也打包过好几个程序呢, pyinstaller 注意事项还是比较多, 研究下它的文档吧
#4 打包的时候加 -c
https://pyinstaller.readthedocs.io/en/stable/usage.html#windows-and-mac-os-x-specific-options
另外可以用 spec 来配置打包命令,方便点
#6 目前来看主要是很多模块无法找到,我怀疑是不是和通过 brew 安装 python3 有关系,但直接运行脚本是没问题的
#7 问题基本明确,warning 中的那些模块找不到,不太清楚 brew 安装的 python3,模块的引用是怎样的,想把模块目录添加进去,发现很分散
#9 建议打开 debug 模式和 console,直接看具体报错,那个 warning 有时候不影响,我在 Windows 下打包也有很多 Warning,但可用
#10
$sudo pyinstaller -F -c --debug main.py
125 INFO: PyInstaller: 3.4.dev0+133d18156
125 INFO: Python: 3.6.2
136 INFO: Platform: Darwin-17.0.0-x86_64-i386-64bit
138 INFO: wrote /Users/goodryb/PycharmProjects/aliyunUI/src/main.spec
149 INFO: UPX is available.
151 INFO: Extending PYTHONPATH with paths
[’/Users/goodryb/PycharmProjects/aliyunUI/src’,
‘/Users/goodryb/PycharmProjects/aliyunUI/src’]
151 INFO: checking Analysis
152 INFO: Building Analysis because out00-Analysis.toc is non existent
152 INFO: Initializing module dependency graph…
155 INFO: Initializing module graph hooks…
157 INFO: Analyzing base_library.zip …
5699 INFO: running Analysis out00-Analysis.toc
5712 INFO: Caching module hooks…
5720 INFO: Analyzing /Users/goodryb/PycharmProjects/aliyunUI/src/main.py
6276 INFO: Processing pre-safe import module hook urllib3.packages.six.moves
9115 INFO: Loading module hooks…
9115 INFO: Loading module hook “hook-requests.py”…
9117 INFO: Loading module hook “hook-PyQt5.py”…
9280 INFO: Loading module hook “hook-xml.etree.cElementTree.py”…
9282 INFO: Loading module hook “hook-encodings.py”…
9407 INFO: Loading module hook “hook-PyQt5.Qt.py”…
9414 INFO: Loading module hook “hook-certifi.py”…
9417 INFO: Loading module hook “hook-PyQt5.QtWidgets.py”…
9419 INFO: Loading module hook “hook-xml.py”…
9519 INFO: Loading module hook “hook-pydoc.py”…
9520 INFO: Loading module hook “hook-PyQt5.QtCore.py”…
9677 INFO: Loading module hook “hook-PyQt5.QtGui.py”…
10381 INFO: Loading module hook “hook-PyQt5.QtPrintSupport.py”…
10537 INFO: Looking for ctypes DLLs
10547 INFO: Analyzing run-time hooks …
10552 INFO: Including run-time hook 'pyi_rth_qt5.py’
10572 INFO: Looking for dynamic libraries
11050 INFO: Looking for eggs
11050 INFO: Using Python library /usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/Python
11056 INFO: Warnings written to /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/warnmain.txt
11119 INFO: Graph cross-reference written to /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/xref-main.html
11144 INFO: checking PYZ
11145 INFO: Building PYZ because out00-PYZ.toc is non existent
11145 INFO: Building PYZ (ZlibArchive) /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/out00-PYZ.pyz
11882 INFO: Building PYZ (ZlibArchive) /Users/goodryb/PycharmProjects/aliyunUI/src/build/main/out00-PYZ.pyz completed successfully.
11898 INFO: checking PKG
11899 INFO: Building PKG because out00-PKG.toc is non existent
11899 INFO: Building PKG (CArchive) out00-PKG.pkg
23726 INFO: Building PKG (CArchive) out00-PKG.pkg completed successfully.
23734 INFO: Bootloader /usr/local/lib/python3.6/site-packages/PyInstaller/bootloader/Darwin-64bit/run_d
23734 INFO: checking EXE
23734 INFO: Building EXE because out00-EXE.toc is non existent
23734 INFO: Building EXE from out00-EXE.toc
23735 INFO: Appending archive to EXE /Users/goodryb/PycharmProjects/aliyunUI/src/dist/main
23793 INFO: Fixing EXE for code signing /Users/goodryb/PycharmProjects/aliyunUI/src/dist/main
23804 INFO: Building EXE from out00-EXE.toc completed successfully.
单文件打开的时候
$./main
[97057] PyInstaller Bootloader 3.x
[97057] LOADER: executable is /Users/goodryb/PycharmProjects/aliyunUI/src/dist/main
[97057] LOADER: homepath is /Users/goodryb/PycharmProjects/aliyunUI/src/dist
[97057] LOADER: _MEIPASS2 is NULL
[97057] LOADER: archivename is /Users/goodryb/PycharmProjects/aliyunUI/src/dist/main
[97057] LOADER: Extracting binaries
[97057] LOADER: Executing self as child
[97057] LOADER: set _MEIPASS2 to /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa
[97058] PyInstaller Bootloader 3.x
[97058] LOADER: executable is /Users/goodryb/PycharmProjects/aliyunUI/src/dist/main
[97058] LOADER: homepath is /Users/goodryb/PycharmProjects/aliyunUI/src/dist
[97058] LOADER: _MEIPASS2 is /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa
[97058] LOADER: archivename is /Users/goodryb/PycharmProjects/aliyunUI/src/dist/main
[97058] LOADER: Already in the child - running user’s code.
[97058] LOADER: Python library: /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa/Python
[97058] LOADER: Loaded functions from Python library.
[97058] LOADER: Manipulating environment (sys.path, sys.prefix)
[97058] LOADER: Pre-init sys.path is /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa/base_library.zip:/var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa
[97058] LOADER: sys.prefix is /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa
[97058] LOADER: Setting runtime options
[97058] LOADER: Initializing python
[97058] LOADER: Overriding Python’s sys.path
[97058] LOADER: Post-init sys.path is /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa/base_library.zip:/var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa
[97058] LOADER: Setting sys.argv
[97058] LOADER: setting sys._MEIPASS
[97058] LOADER: importing modules from CArchive
[97058] LOADER: extracted struct
[97058] LOADER: callfunction returned…
[97058] LOADER: extracted pyimod01_os_path
[97058] LOADER: callfunction returned…
[97058] LOADER: extracted pyimod02_archive
[97058] LOADER: callfunction returned…
[97058] LOADER: extracted pyimod03_importers
[97058] LOADER: callfunction returned…
[97058] LOADER: Installing PYZ archive with Python modules.
[97058] LOADER: PYZ archive: out00-PYZ.pyz
[97058] LOADER: Running pyiboot01_bootstrap.py
[97058] LOADER: Running pyi_rth_qt5.py
[97058] LOADER: Running main.py
objc[97058]: Class RunLoopModeTracker is implemented in both /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa/QtCore (0x10de2a010) and /usr/local/Cellar/qt/5.9.1/lib/QtCore.framework/Versions/5/QtCore (0x112cdf010). One of the two will be used. Which one is undefined.
objc[97058]: Class NotificationReceiver is implemented in both /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa/QtWidgets (0x10f153218) and /usr/local/Cellar/qt/5.9.1/lib/QtWidgets.framework/Versions/5/QtWidgets (0x1131f7218). One of the two will be used. Which one is undefined.
objc[97058]: Class QCocoaPageLayoutDelegate is implemented in both /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa/QtPrintSupport (0x10f372ef0) and /usr/local/Cellar/qt/5.9.1/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport (0x10ff4fef0). One of the two will be used. Which one is undefined.
objc[97058]: Class QCocoaPrintPanelDelegate is implemented in both /var/folders/ks/5f8mgk0s18v3vvtm6fcwjrvr0000gn/T/_MEIFM9gJa/QtPrintSupport (0x10f372f40) and /usr/local/Cellar/qt/5.9.1/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport (0x10ff4ff40). One of the two will be used. Which one is undefined.
QObject::moveToThread: Current thread (0x7ffd8270ba70) is not the object’s thread (0x7ffd824e26a0).
Cannot move to target thread (0x7ffd8270ba70)
You might be loading two sets of Qt binaries into the same process. Check that all plugins are compiled against the right Qt binaries. Export DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.
This application failed to start because it could not find or load the Qt platform plugin "cocoa"
in “”.
Available platform plugins are: cocoa, minimal, offscreen.
Reinstalling the application may fix this problem.
[1] 97057 abort ./main
missing 很多 module 没关系的
你用 terminal 运行看报什么错。。特殊的包比如说 matplotlib canvas 需要特殊支持
我做过 PyQt4 的没问题
这种算是疑难杂症。。去 SO 和 pyinstaller issue 下搜搜
pyinstaller 现在官方 release 版支持 python3.6 了吗?
#12 原文件命令行运行没有任何问题,打包之后运行报错如上
This application failed to start because it could not find or load the Qt platform plugin "cocoa"
in “”.
我去 issue 搜了,似乎没有类似的问题,我提了一个,但是作者并没有正面回复
https://github.com/pyinstaller/pyinstaller/issues/2924
#14 3.3 版本应该是支持了,我使用的是 3.4 dev 版本
不知道怎样把其他库也当作依赖一起打包进去。我整了个包含 MitmProxy 这个库的,但是似乎打包不进去,因此运行 exe 的环境需要有这个库,如果没这个库,exe 不能正常跑。你是否知道怎样一起打包呢?
#16 我也不清楚,我理解应该会自动把所有依赖的包都打进去才对,否则缺少依赖就报错了。
截至目前,我的问题还没有解决
pyinstaller 各种 bug 不稳定。。生产环境还是别用了
#18 打包方便分发,现在只能自己用了
那真是很麻烦了 得配置一堆环境
#20 我已经下载了 xcode,学习下 swift,至少这个打包应该问题不大

