Python中使用pyinstaller打包PyQt应用时常见错误的解决方案

用 pyqt 写了个小工具,要打包给同事用。但是传过去打开后,发现报错了,提示

This application failed to start because it could not find or load the Qt platform plugin windows installing the application may fix this problem

This application failed to start because it could not find or load the Qt platform plugin windows installing the application may fix this problem

但是本机、虚拟机都没问题,32、64bit 也都测了。于是就把问题定位到了系统环境本身的问题,百度了一翻,靠谱的答案没几个。

后面在c++ - Application failed to start because it could not find or load the QT platform plugin "windows" - Stack Overflow让到了解决办法,只需要把platforms 目录拷贝一份,放到打包好的 exe 程序目录下就 Ok 了。

顺便还解决了其他的乱七八糟的缺失 dll 的错误

...
3743 WARNING: lib not found: api-ms-win-crt-process-l1-1-0.dll dependency of c:\python36-32\python36.dll
3862 WARNING: lib not found: api-ms-win-crt-conio-l1-1-0.dll dependency of c:\python36-32\python36.dll
...

类似 lib not found: api-ms-win-xxxxxxxxxxxx.dll这样的提示,直接复制一份到程序所在目录就可以了。

dll 打包

为了方便后面躺坑的,把我的 dll 文件打包传上来,下载地址: https://pan.baidu.com/s/1dTBwui

资料参考

https://stackoverflow.com/questions/21268558/application-failed-to-start-because-it-could-not-find-or-load-the-qt-platform-pl

http://blog.csdn.net/liyuefeilong/article/details/44109403

http://blog.csdn.net/a359680405/article/details/45077187


Python中使用pyinstaller打包PyQt应用时常见错误的解决方案

1 回复

PyQt应用用pyinstaller打包确实容易踩坑,我遇到过不少。直接上几个常见问题的解决方案。

1. 找不到模块/依赖项 最常见的就是打包后运行提示ModuleNotFoundError。PyQt的模块是动态导入的,pyinstaller可能没扫到。解决方案是在spec文件或命令行里显式指定。

# 方法1:命令行添加隐藏导入
pyinstaller --onefile --windowed --hidden-import PyQt5.sip your_script.py

# 方法2:修改spec文件(更推荐)
# 在Analysis部分添加hiddenimports
a = Analysis(['your_script.py'],
             pathex=[],
             binaries=[],
             datas=[],
             hiddenimports=['PyQt5.QtCore', 'PyQt5.QtGui', 'PyQt5.QtWidgets', 'PyQt5.sip'],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=None,
             noarchive=False)

2. 资源文件(如图片、qss)丢失 如果你的应用用了外部资源文件,打包时需要把它们加进去。

# spec文件中datas部分
import os

# 假设有个images文件夹和style.qss文件
def get_data_files():
    data_files = []
    # 添加整个文件夹
    if os.path.exists('images'):
        data_files.append(('images', 'images', 'DATA'))
    # 添加单个文件
    if os.path.exists('style.qss'):
        data_files.append(('style.qss', '.', 'DATA'))
    return data_files

a = Analysis(...,
             datas=get_data_files(),
             ...)

# 代码中访问资源要用sys._MEIPASS
def resource_path(relative_path):
    """获取打包后资源的绝对路径"""
    try:
        base_path = sys._MEIPASS
    except Exception:
        base_path = os.path.abspath(".")
    return os.path.join(base_path, relative_path)

# 使用示例
icon_path = resource_path('images/icon.png')

3. 多进程打包问题 如果你的PyQt程序用了multiprocessing,在Windows上打包后会无限递归。需要在入口添加保护:

import sys
from multiprocessing import freeze_support

def main():
    # 你的PyQt应用代码
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    # 这行必须加!
    freeze_support()
    main()

4. 控制台窗口问题 即使加了--windowed,有时还是会闪黑框。在spec文件中设置:

exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='your_app',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          upx_exclude=[],
          runtime_tmpdir=None,
          console=False,  # 这里确保是False
          icon='icon.ico')

5. 版本兼容性问题 PyQt5和pyinstaller版本不匹配也会出问题。我用的稳定组合是:

PyQt5==5.15.9
pyinstaller==5.13.0

打包命令我一般这样写:

pyinstaller --onefile --windowed --clean --icon=app.ico --add-data "images;images" your_script.py

如果还遇到其他问题,可以先用--debug模式打包,看详细日志找原因。

总结:仔细检查隐藏导入和资源文件路径。

回到顶部