此应用程序无法启动,因为它无法找到或加载 Qt 平台插件“cocoa". [英] This application failed to start because it could not find or load the Qt platform plugin "cocoa"

查看:51
本文介绍了此应用程序无法启动,因为它无法找到或加载 Qt 平台插件“cocoa".的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I think I did everything I could in the last 20 hours, but nothing seems to work. My app is running and working -- just as it should -- the only problem I have is that I cannot create a .app bundle from it. I tried both Py2App and cx_Freeze but non of them is working. Because of the multi-platform support I would stick with the latter -- if possible.

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)

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

The error message I have is this:

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

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

The question is I think pretty obvious: what am I doing wrong? (or what am I not doing?)

推荐答案

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

When building an app with cx_Freeze on MacOSX all dependent libraries (.so files on MacOSX) are packaged into the application bundle. It is this that makes the application portable to other systems, without requiring a second install of Qt.

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

When launching the Application, the libraries should therefore be loaded from within the bundle. However, in your case the system libraries are still being loaded:

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

结果 将使用两者之一.哪个是未定义的. 意味着可以加载其中任何一个.如果它选择了正确的,那就太好了!如果不是,您将同时加载两组独立的库,并且很快就会失败.顺便说一句,您可能会发现,如果您在另一个系统上尝试您的应用程序,它会正常工作!有时.

The result One of the two will be used. Which one is undefined. means that either of these could be loaded. If it picks the correct one, great! If it doesn't you've got two separate sets of libraries loading simultaneously, and that fails shortly afterwards. As an aside, you may find that if you try your Application on another system it will work fine! Sometimes.

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

For an overview of the problem I suggest taking a look at the following bug #33.

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

Make sure you have an up-to-date version of cx_Freeze installed. I would suggest trying to clone the repository and installing from there.

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

Secondly, ensure that the Qt plugins are being correctly built into your application. Cx_Freeze previously looked for the qt-menu.nib file to determine if it was building a Qt application. This is no longer available in Qt5, but you can pass it on the command-line when building your app. Set it to whatever you want, it really doesn't matter:

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

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

This may be enough to fix your problem. But if not, you have two options:

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

Each library file contains the paths to it's dependencies. If you're receiving this error, it means some of those paths are either a) still pointing to the original file, or b) not specific enough (and being found on your PATH or DYLD_LIBRARY_PATH). However, you can re-write paths using install_name_tool from the command line (as described 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 作为基础,重写库中的路径以指向您的应用程序文件夹.您将需要对您发现加载不正确的所有路径执行此操作.我建议将其包装成一个脚本,以便在构建后自动运行.

This rewrites the paths in the libraries to point into your application folder, using @executable_path as the base. You will need to do this for all the paths that you find loading incorrectly. I'd suggest wrapping it up into an script, to run automatically after the build.

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

If you want to look at which libraries a file is referencing you can use otool. For example, in a successfully built application of mine:

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) 
...

在问题跟踪器 表明只需在您的应用中导入正确的模块即可使其正常运行,但您似乎不太可能在没有 QtWidgets 的情况下制作应用.

There was an updated workaround in the issue tracker that suggests that just importing the correct module in your app will get it to function, however it seems unlikely that you've made an application without QtWidgets.

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

If the above doesn't work, there is another approach outlined here. This is a bit of a sledgehammer approach in that it simply prevents loading of plugins at all.

  • 在可执行文件旁边添加一个 qt.conf 文件(在 .app 包中,其中包含:
    <代码>[路径]插件 = '.'

  • Add a qt.conf file next to the executable (in the .app bundle that contains:
    [Paths] Plugins = '.'

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

Either set the environment variable QT_PLUGIN_PATH="" (you can do this within your application before importing PyQt. Or call QtGui.QApplication.setLibraryPaths([]) before creating your application object.

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

The result is no plugins, so your application will not have access to the MacOSX Cocoa style and UI (e.g. file, colour dialogs).

这篇关于此应用程序无法启动,因为它无法找到或加载 Qt 平台插件“cocoa".的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆