過去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
質問は私がかなり明白だと思うことです:私は何を間違っていますか? (または私は何をしていないのですか?)
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つのオプションがあります。
各ライブラリファイルには、依存関係へのパスが含まれています。このエラーを受け取っている場合、それらのパスの一部は、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
なしでアプリケーションを作成した可能性は低いようです。
上記がうまくいかない場合は、 here と概説されている別のアプローチがあります。これは、プラグインのロードをまったく防ぐという点で、ちょっとしたアプローチです。
実行可能ファイルの隣にqt.conf
ファイルを追加します(以下を含む.app
バンドル内)。[Paths] Plugins = '.'
環境変数QT_PLUGIN_PATH=""
を設定します(PyQt
をインポートする前にアプリケーション内でこれを行うことができます。または、アプリケーションオブジェクトを作成する前にQtGui.QApplication.setLibraryPaths([])
を呼び出します。
結果はプラグインではないため、アプリケーションはMacOSX CocoaスタイルとUI(ファイル、カラーダイアログなど)にアクセスできません。
これは、@ 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 でこのディレクトリ構造を正しくセットアップすることをお勧めします。
ncher.app/Contents/MacOS
ディレクトリQt CreatorからQt Widgetsアプリを起動するだけでこの問題が発生しました。
私を助けたのは、変数QT_PLUGIN_PATH
から値<Qt-dir>/plugins
(どこ <Qt-dir>
は、特にbin
、doc
、include
、lib
、そしてもちろんplugins
を含むQtディレクトリ内のフォルダーへの絶対パスです。
これはおそらく問題の根本原因を修正しなかったかもしれませんが、今のところうまく機能している迅速な修正でした。