多くの人がQtとCocoaの接続を求めたと思いますが、インターネット上に明確な情報がなければ、彼らは大きな成功を収めたとは思われません。
エントリー
Qt 4.5までに、TrolltechはCocoa APIの使用を開始しました。これにより、64ビットプラットフォーム用のアプリケーションを構築できます。 Appleが徐々にアプリケーションを32ビットから64ビットに変換していることは注目に値するため、この措置は非常にタイムリーです。
ほとんどの場合、このバージョンで提供される可能性は十分すぎるほどです。
進歩が進んでいるという事実にもかかわらず、ライブラリの新しいバージョンを使用したくない(または使用できない)人々が残っています。 4.5以降では、Cocoaのサポートなしでアセンブリをインストールした人がいます。 この場合、唯一の解決策はCarbonをリンクとして使用することです。
見かけは簡単ですが、そのようなブリッジの組み立ては簡単なことではありません。
QTのドキュメントでは、Objective-Cと組み合わせた使用についてはほとんど言及されていませんが、これらのファイルの拡張子は.mおよび.mmであり、OBJECTIVE_SOURCESディレクティブに関連付けられていますが、それについては後で詳しく説明します。
ブリッジとして、Objective-C ++で記述されたファイルがあります。これにより、C、C ++、Objective-Cを同時に使用できます。 不快な機能は、実装に応じて、クラスがObjective-Cからメッセージを受信するか、QTにスロットを提供できることです。
概略的には、次のようになります。
ソースコード
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
Copy Source | Copy HTML class menuWrapperPrivate ; // Forward declaration @ interface menuWrapperProxy : NSObject { @ private menuWrapperPrivate * wrap; } - ( void ) emitSayHelloRequested; //, Obj-C - ( menuWrapperPrivate *) getQtProxy; // QObject . Qt . @end
クラスはシェルであるため、ほとんど機能を提供しません。 以下は、menuWrapperPrivateの説明です。
Copy Source | Copy HTML
- class menuWrapperPrivate : public QObject
- {
- Q_OBJECT
- 公開 :
- TrayMenu *メニュー。
- 信号:
- void sayHello();
- 公開スロット:
- void privateWrapperSlot(){emit sayHello();};
- };
ご覧のとおり、特別なこともありません。 クラスの唯一のタスクは、Objective-C ++からQt(C ++)に呼び出しを転送することです。
Copy Source | Copy HTML
- @implementation menuWrapperProxy
- -(id)init
- {
- if ((self = [super init])){
- wrap = new menuWrapperPrivate (); // C ++初期化
- wrap-> menu = [[TrayMenu alloc] init]; // Objective-Cの初期化
- [NSApp setDelegate:wrap-> menu];
- [wrap-> menu setParent:self];
- }
- 自己を返す ;
- }
- //メッセージ送信機
- -( void )emitSayHelloRequested
- {
- wrap-> privateWrapperSlot(); // C ++呼び出し
- }
- -( menuWrapperPrivate *)getQtProxy
- {
- 折り返し;
- }
- @end
この部分の主要な行は、メニューの初期化です。 TrayMenuクラスは完全にObjective-Cで記述されています(これにより、多くのソースを変更せずに接続できることを示したかったのです)。 コンパイラーがファイルのタイプを正しく判別できるように、拡張子を.mmにする必要があります(原則として、ファイルのタイプを判別しますが、イデオロギー的にはより正確に判別します)
Copy Source | Copy HTML
- @ interface TrayMenu : NSObject {
- @ プライベート
- NSStatusItem * _statusItem;
- menuWrapperProxy * _parent;
- }
- -( void )setParent:(menuWrapperProxy *)親;
- @end
スペースを節約するために、スクリプトの詳細を意図的に省略しています。
Copy Source | Copy HTML
- @implementation TrayMenu
- //コールバックソース自体。
- -( void )onMyRequest:(id)sender {
- [_parent emitSayHelloRequested];
- }
- -( void )actionQuit:(id)sender {
- [NSApp終了:送信者];
- }
- -(NSMenu *)createMenu {
- NSZone * menuZone = [NSMenu menuZone];
- NSMenu * menu = [[NSMenu allocWithZone:menuZone] init];
- NSMenuItem * menuItem;
- menuItem = [menu addItemWithTitle: @ "Say hello"
- アクション:@selector(onMyRequest :)
- keyEquivalent: @ "" ];
- [menuItem setTarget:self];
- [メニューaddItem:[NSMenuItem separatorItem]];
- menuItem = [menu addItemWithTitle: @ "Quit"
- アクション:@selector(actionQuit :)
- keyEquivalent: @ "" ];
- [menuItem setToolTip: @ "クリックしてこのアプリを終了" ];
- [menuItem setTarget:self];
- 戻りメニュー。
- }
- //リソースの読み込みの終了後に呼び出されるオーバーロードされた関数
- -( void )applicationDidFinishLaunching:(NSNotification *)通知{
- NSMenu * menu = [self createMenu];
- _statusItem = [[[NSStatusBar systemStatusBar] //ステータスバーを取得
- statusItemWithLength:NSVariableStatusItemLength] retain];
- [_statusItem setMenu:menu];
- [_statusItem setTitle: @ "Menu" ];
- [_statusItem setHighlightMode:YES];
- [_statusItem setToolTip: @ "Test Tray" ];
- [メニューリリース];
- }
- -( void )setParent:(menuWrapperProxy *)親
- {
- _parent = parent;
- }
- @end
メニューボタンを押すと、シェルおよびプロキシクラスを介してQtアプリケーションに入るイベントが生成されます。 スキームは、より複雑なケースで異なることはほとんどありません。 ファイル拡張子.mに良いトーンを与えます。
Copy Source | Copy HTML
- menuWrapperProxy * mwp = [[menuWrapperProxy alloc] init];
- menuWrapperPrivate * signalWrapper = [mwp getQtProxy];
- QMessageBox * box = new QMessageBox(0);
- connect (signalWrapper、SIGNAL(sayHello())、box、SLOT( exec ()));
ちょうどいい? 異なる言語のObj-C ++とクラスが互いに理解し合うことはほとんどありません。
次に、コンパイラにこのすべての恐怖を収集させる必要があります。
ドキュメントでは、.proファイルに指示を追加する必要があります(または、以下を読む)。
OBJECTIVE_SOURCES + = file1.m file2.mm
問題は、最初はqmakeがObective-Cファイルを処理できず、Objective-C ++のみを処理できることです。
スマートな紙片の長期喫煙、タンバリンとのダンス、突っ込む方法は、私が決断を下すのに役立ちました-方向を追加します:
QMAKE_CXXFLAGS = -ObjC ++
QMAKE_CFLAGS = -ObjC ++。
100%真実かどうかはわかりませんが、QMakeディレクティブに関係なく、コードをコンパイルして任意のプロジェクトファイルにObjective-C ++で記述できます。
おわりに
この記事があなたのプロジェクトで役立つことを願っています。 インターネット上の他の例とは異なり、コードは機能しており、正直なObjective-Cクラスが含まれており、あいまいなライブラリを必要としません。 ヘッダーファイルを正しく配置するだけで、30分以上かかりません。
PSここでは、プロジェクト全体を投稿しました。これはコンパイルしやすいでしょう。