答えて
それはクレイジーだが、私はそれを得た、と任意のObjective-Cのコーディングなし:
私ははQApplicationを導出しました。私の派生クラスの* .cppファイルの部分では私が入れ:私は置く私の派生アプリケーションクラスのコンストラクタで
#ifdef Q_OS_MAC
#include <objc/objc.h>
#include <objc/message.h>
bool dockClickHandler(id self,SEL _cmd,...)
{
Q_UNUSED(self)
Q_UNUSED(_cmd)
((MyApplictionClass*)qApp)->onClickOnDock();
return true;
}
#endif
:
#ifdef Q_OS_MAC
objc_object* cls = objc_getClass("NSApplication");
SEL sharedApplication = sel_registerName("sharedApplication");
objc_object* appInst = objc_msgSend(cls,sharedApplication);
if(appInst != NULL)
{
objc_object* delegate = objc_msgSend(appInst, sel_registerName("delegate"));
objc_object* delClass = objc_msgSend(delegate, sel_registerName("class"));
const char* tst = class_getName(delClass->isa);
bool test = class_addMethod((objc_class*)delClass, sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:"), (IMP)dockClickHandler,"[email protected]:");
if (!test)
{
// failed to register handler...
}
}
#endif
追加するこの単純な方法で自分のアプリケーションクラスに(注意それはから参照されます私の答えの先頭にあるハンドラ)
void MyApplictionClass::onClickOnDock()
{
// do something...
}
魅力的な作品です。
廃止の警告(post-OS X 10.5)とタイプエラーのため、元の回答が正しくコンパイルできませんでした。いくつかの型名を変更してコンパイルしましたが、コードはまだ機能しませんでした。
Qtの新しいバージョン(5.8を含む4.8.7+;私は5.4.1を使用しています)が追加したいメソッドを実装しており、メソッドがすでに存在する場合はclass_addMethod
が失敗します。 this QTBUGを参照してください。
注:上記のバグレポートには少し異なる解決策が含まれています(問題を自分で解決した後に見つけました)。
私にとっては、方法が存在するかどうかを確認する1つの解決策です。そうであれば、それを置き換えます。そうでない場合は、単に追加します。
私は古いQtバージョンでこのコードをテストしていませんが、OPロジックを使用しているので動作するはずです。
ここに私のコードです。 OPの場合と同様に、すべてのコードはQApplicationサブクラスの.cppファイルにあります。
#ifdef Q_OS_MAC
#include <objc/objc.h>
#include <objc/message.h>
void setupDockClickHandler();
bool dockClickHandler(id self,SEL _cmd,...);
#endif
私はQApplicationサブクラスのコンストラクタは
#ifdef Q_OS_MAC
setupDockClickHandler();
#endif
そして最後に、どこか(私の場合は一番下に、)同じファイル内に含まれています
#ifdef Q_OS_MAC
void setupDockClickHandler() {
Class cls = objc_getClass("NSApplication");
objc_object *appInst = objc_msgSend((objc_object*)cls, sel_registerName("sharedApplication"));
if(appInst != NULL) {
objc_object* delegate = objc_msgSend(appInst, sel_registerName("delegate"));
Class delClass = (Class)objc_msgSend(delegate, sel_registerName("class"));
SEL shouldHandle = sel_registerName("applicationShouldHandleReopen:hasVisibleWindows:");
if (class_getInstanceMethod(delClass, shouldHandle)) {
if (class_replaceMethod(delClass, shouldHandle, (IMP)dockClickHandler, "[email protected]:"))
qDebug() << "Registered dock click handler (replaced original method)";
else
qWarning() << "Failed to replace method for dock click handler";
}
else {
if (class_addMethod(delClass, shouldHandle, (IMP)dockClickHandler,"[email protected]:"))
qDebug() << "Registered dock click handler";
else
qWarning() << "Failed to register dock click handler";
}
}
}
bool dockClickHandler(id self,SEL _cmd,...) {
Q_UNUSED(self)
Q_UNUSED(_cmd)
// Do something fun here!
qDebug() << "Dock icon clicked!";
// Return NO (false) to suppress the default OS X actions
return false;
}
#endif
もApple documentation on the applicationShouldHandleReopen:hasVisibleWindows: methodを参照してください。
これをコンパイルするには、いくつかの余分なフレームワークもリンクする必要があります。これらのフラグは、手動でコンパイル場合は、C++または打ち鳴らす++コマンドラインに追加する必要があります正確に何もちろんです
LIBS += -framework CoreFoundation -framework Carbon -lobjc
:qmakeのを使用して
は、私は私の.PROファイルに次を追加しました。
これはすべて必要なものです。
です。それは良い答えですが、私はそれを客観的なC. qmakeの使用を避ける必要があるとは思いません。Qmakeは '.mm'ファイルからインクルードされたときに有効です。これは単にobj-C++で '.mm'ファイルで記述することができ、objcランタイムへの明示的な呼び出しがなくても少し読みやすくなります。 MacのQtプロジェクトには.mと.mmファイルを含めることができます。また、.mmファイルからQtを使用することもできます。 –
Qt5.4.0から、QEventを処理することができます。これは、Dock:QEvent :: ApplicationActivateをクリックすることに関連しています。
QEventに問題:: ApplicationActivateは、それがすべての活性化のために放出されることである - 例えば、あなたがアプリケーションスイッチャーのアプリに切り替えた場合でも。ネイティブの振る舞いは、Dockのアイコンをクリックするだけで、cmd +タブで切り替えるときではなく、アプリを表示することです。
しかし、少なくともQt 5.9.1では機能するハックがあります。 Dockアイコンをクリックすると、2つのシーケンシャルなQEvent :: ApplicationStateChangeEventイベントが生成されますが、cmd +タブは1つのみです。 このコードはDockのクリック信号を非常に正確に出力します。 Appクラスは、QApplicationから継承されたアプリケーションクラスであり、それ自体のイベントフィルタです。
bool App::eventFilter(QObject* watched, QEvent* event)
{
#ifdef Q_OS_MACOS
if (watched == this && event->type() == QEvent::ApplicationStateChange) {
auto ev = static_cast<QApplicationStateChangeEvent*>(event);
if (_prevAppState == Qt::ApplicationActive
&& ev->applicationState() == Qt::ApplicationActive) {
emit clickedOnDock();
}
_prevAppState = ev->applicationState();
}
#endif // Q_OS_MACOS
return QApplication::eventFilter(watched, event);
}
- 1. メニューバーアプリケーションがDockアイコン(Mac OS X)によって起動されています
- 2. Javascript - x-webkit-speechアイコンのクリックを検出します。
- 3. Mac OSのQt - ドックメニューのクリックを検出する
- 4. Qt Creator(Mac OS X)にQt SDKを追加する方法
- 5. Qtのツールチップ内でマウスのクリックを検出する方法は?
- 6. OS Xの用紙切れを検出する方法は?
- 7. Dockアイコンをドロップする
- 8. アプリでiPhone OSのバージョンを検出する方法は?
- 9. Qt Dockをカスタマイズする
- 10. Qt/Mac Dockアイコンを変更すると、ウィンドウキャプションの副作用が発生する
- 11. マウスでMac OSをクリックして実行中のOSアプリケーションを検出します
- 12. Qt CreatorをOS Xにインストール
- 13. Mac OS X Dockの位置、幅、高さを取得するには? Cocoa/Carbon/C++/Qt
- 14. シェルからMac OS Xの現在のロケールを検出する方法
- 15. OS X上のAWT PrinterJobから 'Save as PDF ...'を検出する方法
- 16. Eclipse Dockアイコンを変更する
- 17. Dockアイコンのボリュームドロップを受け入れる
- 18. Mac OS Xでのピッチ検出
- 19. OS XでBluetooth検出可能モードをプログラムで設定する方法
- 20. C#を使用してシステムトレイのアイコンを右クリックする方法
- 21. XCode 5 OS Xアプリのリモートデバッグ
- 22. アイコンQt QTreeWidgetをクリックしてください
- 23. アイコンをクリックして外部ツールを実行する方法
- 24. Mac OS Xで時間コマンド出力をリダイレクトする方法
- 25. Javascriptでライオン(OS X 10.7)を検出しますか?
- 26. Mac OS X上のQT、QFileSystemModelでSetRootPath
- 27. iOSアプリのアイコン - 方法
- 28. OS XでCLIを使用してファイルまたはディレクトリにアイコンを設定する方法は?
- 29. OS X用スタンドアローンDjangoアプリ
- 30. ボリュームがOS Xにマウントされたことを検出する
ありがとうございました!明らかに、このコードはQt 4.8.7で動作しなくなりましたが、Qt 5.4.1で動作させることができたので、私は更新されたバージョンで答えを投稿しました。 – exscape
これは私には役に立たない。エキスパートの答えは ' –