web-dev-qa-db-ja.com

このアプリケーションは、Qtプラットフォームプラグイン「cocoa」を検出またはロードできなかったため、起動に失敗しました

過去20時間でできることはすべてやりましたが、何も機能していないようです。私のアプリは実行されており、動作している-まさにそうである-私が持っている唯一の問題は、.appバンドル。両方試してみましたPy2Appおよびcx_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

質問は私がかなり明白だと思うことです:私は何を間違っていますか? (または私は何をしていないのですか?)

37
Peter Varo

MacOSXでcx_Freezeを使用してアプリをビルドすると、すべての依存ライブラリ(MacOSXの.soファイル)がアプリケーションバンドルにパッケージ化されます。これにより、Qtの2回目のインストールを必要とせずに、アプリケーションを他のシステムに移植できるようになります。

そのため、アプリケーションを起動するときに、ライブラリをバンドル内からロードする必要があります。ただし、あなたの場合、システムライブラリはまだロードされています:

/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.は、これらのいずれかをロードできることを意味します。正しいものを選択した場合、素晴らしい!そうでない場合は、2つの別個のライブラリセットが同時にロードされ、すぐに失敗します。余談ですが、別のシステムでアプリケーションを試してみてもうまくいくことがあります! 時々

問題の概要については、次の bug# をご覧になることをお勧めします。

あなたが始める前に

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/

これで問題を解決できます。ただし、そうでない場合は、2つのオプションがあります。

オプション1

各ライブラリファイルには、依存関係へのパスが含まれています。このエラーを受け取っている場合、それらのパスの一部は、a)元のファイルを指しているか、b)十分に特定されていない(PATHまたはDYLD_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) 
...

課題追跡システムの更新された回避策 があり、アプリに正しいモジュールをインポートするだけで機能するようになりますが、QtWidgetsなしでアプリケーションを作成した可能性は低いようです。

オプション2

上記がうまくいかない場合は、 here と概説されている別のアプローチがあります。これは、プラグインのロードをまったく防ぐという点で、ちょっとしたアプローチです。

  • 実行可能ファイルの隣にqt.confファイルを追加します(以下を含む.appバンドル内)。
    [Paths] Plugins = '.'

  • 環境変数QT_PLUGIN_PATH=""を設定します(PyQtをインポートする前にアプリケーション内でこれを行うことができます。または、アプリケーションオブジェクトを作成する前にQtGui.QApplication.setLibraryPaths([])を呼び出します。

結果はプラグインではないため、アプリケーションはMacOSX CocoaスタイルとUI(ファイル、カラーダイアログなど)にアクセスできません。

6
mfitzp

これは、@ mfitzpの回答に追加されます。

この QTプラグインドキュメント が役立ちました。

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 でこのディレクトリ構造を正しくセットアップすることをお勧めします。

DONTは、フレームワーク、プラグインをncher.app/Contents/MacOSディレクトリ

2
PnotNP

Qt CreatorからQt Widgetsアプリを起動するだけでこの問題が発生しました。

私を助けたのは、変数QT_PLUGIN_PATHから値<Qt-dir>/plugins (どこ <Qt-dir>は、特にbindocincludelib、そしてもちろんpluginsを含むQtディレクトリ内のフォルダーへの絶対パスです。

これはおそらく問題の根本原因を修正しなかったかもしれませんが、今のところうまく機能している迅速な修正でした。

0
rsp1984