【问题标题】:This application failed to start because it could not find or load the Qt platform plugin "cocoa"此应用程序无法启动,因为它无法找到或加载 Qt 平台插件“cocoa”
【发布时间】:2014-10-01 00:39:48
【问题描述】:

我想我在过去 20 小时内已尽我所能,但似乎没有任何效果。我的应用程序正在运行和工作——正如它应该的那样——我唯一的问题是我无法从中创建.app 包。我尝试了Py2Appcx_Freeze,但它们都没有工作。由于多平台支持,我会坚持使用后者——如果可能的话。

setup.py 看起来像这样:

import sys
from cx_Freeze import setup, Executable

base = None
if sys.platform == 'win32':
    base = 'Win32GUI'

OPTIONS = {'build_exe': {'includes': ['sip',
                                      'PyQt5',
                                      'PyQt5.QtCore',
                                      'PyQt5.QtGui',
                                      'PyQt5.QtWidgets',
                                      'PyQt5.QtMultimediaWidgets',
                                      'PyQt5.QtMultimedia',
                                      'PyQt5.QtNetwork']}}

EXECUTABLES = [Executable('main.py', base=base)]
NAME = 'coublet'
VERSION = '0.5.70'

setup(name = NAME,
      version = VERSION,
      options = OPTIONS,
      executables = EXECUTABLES)

我收到的错误信息是这样的:

objc[28404]: Class NotificationReceiver is implemented in both
/Users/.../build/coublet-0.5.70.app/Contents/MacOS/QtWidgets and
/usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets. One of
the two will be used. Which one is undefined.
QObject::moveToThread: Current thread (0x7fc4b96e98b0) is not the object's thread
(0x7fc4b95dbc80).
Cannot move to target thread (0x7fc4b96e98b0)

On Mac OS X, 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".

Available platform plugins are: cocoa, minimal, offscreen.

Reinstalling the application may fix this problem.
Abort trap: 6

我的系统信息:

Mac OS X  : 10.9.4
Python    :  3.4.1
cx_Freeze :  0.9
PyQt5:    :  5.3.1
- - -
Packages installed via: Homebrew and PIP

.app结构:

build/coublet-0.5.70.app
└── Contents
    ├── Frameworks
    ├── Info.plist
    ├── MacOS
    │   ├── PyQt5.QtCore.so
    │   ├── PyQt5.QtGui.so
    │   ├── PyQt5.QtMultimedia.so
    │   ├── PyQt5.QtMultimediaWidgets.so
    │   ├── PyQt5.QtNetwork.so
    │   ├── PyQt5.QtWidgets.so
    │   ├── Python
    │   ├── QtCore
    │   ├── QtCore.so
    │   ├── QtGui
    │   ├── QtGui.so
    │   ├── QtMultimedia
    │   ├── QtMultimedia.so
    │   ├── QtMultimediaWidgets
    │   ├── QtMultimediaWidgets.so
    │   ├── QtNetwork
    │   ├── QtNetwork.so
    │   ├── QtOpenGL
    │   ├── QtWidgets
    │   ├── QtWidgets.so
    │   ├── _bisect.so
    │   ├── _bz2.so
    │   ├── _codecs_cn.so
    │   ├── _codecs_hk.so
    │   ├── _codecs_iso2022.so
    │   ├── _codecs_jp.so
    │   ├── _codecs_kr.so
    │   ├── _codecs_tw.so
    │   ├── _datetime.so
    │   ├── _hashlib.so
    │   ├── _heapq.so
    │   ├── _json.so
    │   ├── _lzma.so
    │   ├── _md5.so
    │   ├── _multibytecodec.so
    │   ├── _opcode.so
    │   ├── _pickle.so
    │   ├── _posixsubprocess.so
    │   ├── _random.so
    │   ├── _scproxy.so
    │   ├── _sha1.so
    │   ├── _sha256.so
    │   ├── _sha512.so
    │   ├── _socket.so
    │   ├── _ssl.so
    │   ├── _struct.so
    │   ├── array.so
    │   ├── binascii.so
    │   ├── grp.so
    │   ├── imageformats
    │   │   ├── libqdds.dylib
    │   │   ├── libqgif.dylib
    │   │   ├── libqicns.dylib
    │   │   ├── libqico.dylib
    │   │   ├── libqjp2.dylib
    │   │   ├── libqjpeg.dylib
    │   │   ├── libqmng.dylib
    │   │   ├── libqsvg.dylib
    │   │   ├── libqtga.dylib
    │   │   ├── libqtiff.dylib
    │   │   ├── libqwbmp.dylib
    │   │   └── libqwebp.dylib
    │   ├── libcrypto.1.0.0.dylib
    │   ├── liblzma.5.dylib
    │   ├── library.zip
    │   ├── libreadline.6.dylib
    │   ├── libssl.1.0.0.dylib
    │   ├── main
    │   ├── math.so
    │   ├── platforms
    │   │   ├── libqcocoa.dylib
    │   │   ├── libqminimal.dylib
    │   │   └── libqoffscreen.dylib
    │   ├── pyexpat.so
    │   ├── readline.so
    │   ├── select.so
    │   ├── sip.so
    │   ├── termios.so
    │   ├── time.so
    │   ├── unicodedata.so
    │   └── zlib.so
    └── Resources

我认为问题很明显:我做错了什么? (或者我没有做什么?)

【问题讨论】:

  • 只是一个建议:您可以暂时删除 /usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets (例如通过重命名或通过自制软件删除) .它应该可以让您成功构建应用程序包。
  • 我在 Windows 上得到了同样的结果。我必须自己将libEGL.dll 添加到主应用程序目录中。那么也许 OS X 上有类似的动态库?

标签: macos python-3.x bundle cx-freeze pyqt5


【解决方案1】:

在 MacOSX 上使用 cx_Freeze 构建应用程序时,所有依赖库(MacOSX 上的 .so 文件)都打包到应用程序包中。正是这使得应用程序可以移植到其他系统,而无需第二次安装 Qt。

因此,在启动应用程序时,应从包中加载库。但是,在您的情况下,系统库仍在加载中:

/Users/.../build/coublet-0.5.70.app/Contents/MacOS/QtWidgets
/usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets

结果One of the two will be used. Which one is undefined. 表示可以加载其中任何一个。如果它选择了正确的,那就太好了!如果不是,您将同时加载两组独立的库,并且很快就会失败。顺便说一句,您可能会发现,如果您在另一个系统上尝试您的应用程序,它会正常工作! 有时

对于问题的概述,我建议查看以下bug #33

开始之前

确保您安装了最新版本的cx_Freeze。我建议尝试克隆存储库并从那里安装。

其次,确保 Qt 插件正确地内置到您的应用程序中。 Cx_Freeze 之前查找qt-menu.nib 文件以确定它是否正在构建Qt 应用程序。这在 Qt5 中不再可用,但您可以在构建应用程序时在命令行上传递它。设置成你想要的,真的没关系:

python setup.py bdist_mac --qt-menu-nib=/usr/local/Cellar/qt5/5.3.1/plugins/platforms/

这可能足以解决您的问题。但如果没有,您有两种选择:

选项 1

每个库文件都包含其依赖项的路径。如果您收到此错误,这意味着其中一些路径是 a) 仍然指向原始文件,或者 b) 不够具体(并且在您的 PATHDYLD_LIBRARY_PATH 上找到)。但是,您可以在命令行中使用install_name_tool 重写路径(如here 所述:

install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtWidgets.framework/Versions/5/QtWidgets @executable_path/QtWidgets build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib
install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtCore.framework/Versions/5/QtCore @executable_path/QtCore build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib
install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtPrintSupport.framework/Versions/5/QtPrintSupport @executable_path/QtPrintSupport build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib
install_name_tool -change /usr/local/Cellar/qt5/5.3.1/lib/QtGui.framework/Versions/5/QtGui @executable_path/QtGui build/MyApp.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib

这会重写库中的路径以指向您的应用程序文件夹,使用 @executable_path 作为基础。您将需要对您发现加载不正确的所有路径执行此操作。我建议将其包装成一个脚本,以便在构建后自动运行。

如果您想查看文件引用了哪些库,您可以使用otool。例如,在我成功构建的应用程序中:

otool -L libqcocoa.dylib 
libqcocoa.dylib:
    @executable_path/../Resources/qt_plugins/platforms/libqcocoa.dylib (compatibility version 0.0.0, current version 0.0.0)
    /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 20.0.0) 
...

有一个updated workaround in the issue tracker 表明只需在您的应用中导入正确的模块即可使其正常运行,但您似乎不太可能在没有QtWidgets 的情况下创建应用。

选项 2

如果上述方法不起作用,还有另一种方法概述了here。这有点像大锤的方法,因为它根本阻止加载插件。

  • 在可执行文件旁边添加一个qt.conf 文件(在包含以下内容的.app 捆绑包中:
    [Paths] Plugins = '.'

  • 设置环境变量QT_PLUGIN_PATH=""(您可以在导入PyQt之前在应用程序中执行此操作。或者在创建应用程序对象之前调用QtGui.QApplication.setLibraryPaths([])

结果是没有插件,因此您的应用程序将无法访问 MacOSX Cocoa 样式和 UI(例如文件、颜色对话框)。

【讨论】:

  • 很好的答案。你能看看这个问题吗:stackoverflow.com/questions/45858376/…
  • 文件:dist/fullmain.app/Contents/MacOS/qt_plugins/platforms/libqcocoa.dylib(没有这样的文件或目录)
【解决方案2】:

使用这个命令:

pip install opencv-python-headless

在我的情况下它解决了同样的问题。

【讨论】:

    【解决方案3】:

    这是对@mfitzp 的回答。

    这个QT Plugins Document 派上用场了。

    要查找您的 QT 应用程序尝试搜索的默认位置,您可以使用以下命令:

    $sudo dtruss MacOS/ncher 
      getattrlist("/ncher.app\0", 0x7FFF954B51A4, 0x7FFF5C8FDD20)              = 0 0
      getattrlist("/ncher.app/Contents\0", 0x7FFF954B51A4, 0x7FFF5C8FDD20)             = 0 0
      getattrlist("/ncher.app/Contents/MacOS\0", 0x7FFF954B51A4, 0x7FFF5C8FDD20)               = 0 0
      stat64("/ncher.app/Contents/MacOS\0", 0x7FFF5C8FDED8, 0x7FFF5C8FDD20)            = 0 0
      stat64("/ncher.app/Contents/MacOS/platforms/.\0", 0x7FFF5C8FDF58, 0x7FFF5C8FDD20)                = -1 Err#2
      open("/dev/tty\0", 0x1000000, 0x1FF)             = 5 0
      fcntl(0x5, 0x2, 0x1)             = 0 0
      close(0x5)               = 0 0
      write_nocancel(0x2, "This application failed to start because it could not find or load the Qt platform plugin \"cocoa\".\n\nReinstalling the application may fix this problem.\n\0", 0x97)              = 151 0
      sigprocmask(0x3, 0x7FFF5C8FE6B4, 0x0)            = 0x0 0
      __pthread_sigmask(0x3, 0x7FFF5C8FE6C0, 0x0)              = 0 0
      __pthread_kill(0x603, 0x6, 0x0)          = 0 0
      kevent64(0x4, 0x0, 0x0)          = -1 Err#4
    

    你可以看到这个 QT 应用程序试图查看MacOS/platforms,一旦我复制了我的 libqcocoa.dylib 插件(它的路径由install_name_tool 命令根据@mfitzp 的回答修改),我的应用程序就像魅力一样工作。

    顺便说一句,MAC codesigning guide 建议正确设置此目录结构,

    不要将框架、插件放在ncher.app/Contents/MacOS 目录中

    【讨论】:

    【解决方案4】:

    我刚从 Qt Creator 启动 Qt Widgets 应用时遇到了这个问题。

    帮助我的是将变量QT_PLUGIN_PATH 设置为值<Qt-dir>/plugins(其中<Qt-dir> 是Qt 目录中文件夹的绝对路径,其中包含bindoc、@ 987654326@、lib,当然还有plugins)。

    这可能没有解决问题的根本原因,但它是一个快速修复,到目前为止运行良好。

    【讨论】:

      猜你喜欢
      • 2014-04-11
      • 2016-06-10
      • 2015-06-06
      • 2017-07-24
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      • 2019-07-26
      相关资源
      最近更新 更多