You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyInstaller生成EXE遇qtpy.QtBindingsNotFoundError求解决方案

PyInstaller打包PyQt6+qtmodern项目时出现QtBindingsNotFoundError的解决建议

报错信息

运行生成的EXE文件时持续触发以下错误:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    import qtmodern.styles
  File "pyimod02_importers.py", line 457, in exec_module
  File "qtmodern\styles.py", line 3, in <module>
  File "pyimod02_importers.py", line 457, in exec_module
  File "qtpy\__init__.py", line 293, in <module>
qtpy.QtBindingsNotFoundError: No Qt bindings could be found
[PYI-44852:ERROR] Failed to execute script 'main' due to unhandled exception!

打包命令

使用的打包命令:

poetry run pyinstaller main.spec --clean

相关文件内容

main.spec

# -*- mode: python ; coding: utf-8 -*-

a = Analysis(
    ['main.py'],
    pathex=['fullpathonmypc\.venv\Lib\site-packages'],
    binaries=[],
    datas=[],
    hiddenimports= ["qtmodern", "qtmodern.styles", "qtmodern.windows",
    "qtpy", "qtpy.QtCore", "qtpy.QtGui", "qtpy.QtWidgets",
    "PyQt6.QtCore", "PyQt6.QtGui", "PyQt6.QtWidgets",
    "PyQt6.QtPrintSupport", "PyQt6.QtSvg", "PyQt6.QtOpenGL", "event_connector", "numpy"],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=['PySide6'],
    noarchive=False,
    optimize=0,
)
pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    [],
    exclude_binaries=True,
    name='main',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)
coll = COLLECT(
    exe,
    a.binaries,
    a.datas,
    strip=False,
    upx=True,
    upx_exclude=[],
    name='main',
)

hooks\hook-qtmodern.py

from PyInstaller.utils.hooks import collect_submodules
hiddenimports = collect_submodules("qtmodern")

hooks\hook-qtpy.py

from PyInstaller.utils.hooks import collect_submodules
hiddenimports = collect_submodules("qtpy")

已尝试的排查措施

  • 在main.spec的hiddenimports列表中添加所有相关模块
  • 创建hooks\hook-qtpy.py文件
  • 在main.py报错行前添加代码os.environ["QT_API"] = "pyqt6"
  • 在虚拟环境中执行poetry run python -c "import qtpy; import PyQt6; print(qtpy.API_NAME)",确认输出为"PyQt6"
  • 在main.spec的binaries列表中添加collect_dynamic_libs("PyQt6"),因打包报错ValueError: not enough values to unpack (expected 2, got 0)移除
  • 执行pyi-archive_viewer main.exe确认PyQt6已被打包
  • 查阅文档得知Qt 6暂不被PyInstaller完全支持,插件无法复制
  • 不带--onefile参数、带--clean参数重新生成main.spec,迁移原有配置
  • 向ChatGPT求助并遵循建议
  • 在main.spec的datas中添加collect_data_files("PyQt6"),因打包报错移除
  • 在main.spec的hiddenimports中添加collect_submodules("qtpy") + collect_submodules("PyQt6")的内容

解决建议

  1. 修复pathex路径格式:Windows路径反斜杠需转义或改用正斜杠,将pathex中的'fullpathonmypc\.venv\Lib\site-packages'修改为'fullpathonmypc/.venv/Lib/site-packages'或'fullpathonmypc\\.venv\\Lib\\site-packages',避免路径解析错误导致依赖查找失败。

  2. 加载自定义钩子:当前hookspath为空,PyInstaller无法识别你创建的钩子。修改Analysis部分的hookspath=[]为hookspath=['./hooks'],确保钩子被加载。同时完善hook-qtpy.py:

from PyInstaller.utils.hooks import collect_submodules, collect_data_files
hiddenimports = collect_submodules("qtpy")
datas = collect_data_files("qtpy")
  1. 手动复制Qt插件:找到虚拟环境中PyQt6的插件目录(一般为./.venv/Lib/site-packages/PyQt6/Qt6/plugins),将整个plugins文件夹复制到打包后的main目录下(与main.exe同级)。

  2. 添加运行时钩子强制配置环境变量:创建hooks/runtime_hook.py文件,内容如下:

import os
os.environ["QT_API"] = "pyqt6"
# 手动指定Qt插件路径
os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = os.path.join(os.path.dirname(os.path.abspath(__file__)), "../plugins")

然后在main.spec的Analysis部分添加runtime_hooks=['./hooks/runtime_hook.py'],确保程序启动时就加载正确的环境配置。

  1. 禁用UPX压缩Qt相关文件:UPX可能破坏Qt动态链接库,将EXE和COLLECT部分的upx=True改为upx=False,避免压缩导致的依赖损坏。

  2. 重新生成基础spec再调整配置:先运行poetry run pyinstaller main.py --noconsole --hidden-import=qtmodern --hidden-import=qtpy --hidden-import=PyQt6生成基础spec文件,再手动添加excludes、hookspath、runtime_hooks等配置,减少手动编写spec的错误。

内容的提问来源于stack exchange,提问作者AGA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:43:20