2016-08-06 3 views
7

私はQMenuQActionを持っています。 QActiontriggered()の場合、どのボタンがそれをしたのか知りたいです。QActionが左または右マウスボタンでクリックされているかどうかを知りたい

connect(YourAction, SIGNAL(triggered()), this, SLOT(actionclicked())); 

void MainWindow::actionclicked(QMouseEvent *e) 
{ 
    if (e->buttons() == Qt::RightButton) 
} 

triggered()は、このような引数を持っていないので、私はこのような何かを行うことはできません。それ単独では、必ずしもマウスイベントの結果れていないため

答えて

4

@mvidelgauzに告知されているように、入力デバイスからは、アクションを引き起こす可能性のある入力デバイスから抽象化されています。それにもかかわらず、あなたのGUIでアクションが使用されている場合は、ツールバーのツールボタン、メニューバーの項目など、関連付けられたウィジェットが1つ以上あります。これらのウィジェットは他のウィジェットと同じように動作し、installEventFiltereventFilterを使用してフィルタリングされる可能性のあるイベントを受け取ります。これらの2つのメソッドはQObjectから継承されているため、ほぼすべてのQtクラスに存在します。たとえば、QMainWindowとQActionがactionTestというアプリケーションを作成してみましょう。その後のメインウィンドウのeventFilterメソッドをオーバーライドしてactionTestの関連するウィジェットのアクションフィルタにメインウィンドウ自体を回してみましょう:

bool eventFilter(QObject *obj, QEvent *ev) { 
    //Catch only mouse press events. 
    if(ev->type() == QEvent::MouseButtonPress) { 
     // Cast general event to mouse event. 
     QMouseEvent *mev = static_cast<QMouseEvent*>(ev); 
     // Show which button was clicked. 
     if(mev->button() == Qt::LeftButton) { 
      qDebug() << "Left button!"; 
     } 
     if(mev->button() == Qt::RightButton) { 
      qDebug() << "Right button!"; 
     } 
    } 
    // In this example we just showed the clicked button. Pass the event 
    // for further processing to make QAction slots work. 
    return QMainWindow::eventFilter(obj, ev); 
} 

その後、我々は我々の場合のウィジェットであるすべて見オブジェクトのイベントフィルタオブジェクトをインストールする必要があります。のは、メインウィンドウのコンストラクタでそれをやってみましょう:

MainWindow::MainWindow(QWidget *parent) : 
QMainWindow(parent), 
ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    for(auto wgtPtr : ui->actionTest->associatedWidgets()) { 
     wgtPtr->installEventFilter(this); 
    } 
} 

最後に、triggered()信号処理のためのスロットを追加します:あなたは、マウスの左ボタンでアクションメニュー項目をクリックすると

void on_actionTest_triggered() { 
    qDebug() << "Action triggered!"; 
} 

さて、それは

を印刷します
Left button! 
Action triggered! 

マウスの右ボタンの結果は次のようになりますしながら、

Right button! 
Action triggered! 

ウィジェットイベントフィルタリングは、常にtriggered()シグナルが放出される前に実行されることに注意してください。

上記のコードは単なる例であり、MainWindowクラスはeventFilterメソッドをホストするのに最適な場所ではありません。あなたはどちらかかもしれない実際のコードでは:

  1. QActionウィジェットイベントのフィルタリングのための専用QObjectサブクラス(複数可)を作成します。
  2. サブクラスQActionをオーバーライドし、eventFilterメソッドをオーバーライドします。この場合、QMouseEvent::button()の結果をQActionサブクラスオブジェクトに保存し、後でtriggered()シグナルハンドラで使用することができます。 Qtの作成者(少なくともv3.2.1まで)は、フォームデザイナーでQActionを "昇進"させないため、ウィンドウコンストラクターでメニューに手動でアクションを追加する必要があります。
  3. サブクラスQMenuQToolBarなど、アクションフィルタを作成しますか?私はそれが2つの元の変種よりも優れているのかどうかはわかりません。

Qtイベントシステムについてもdocumentationを参照してください。

ケース2を明らかにする。QActionから継承したクラスをMyActionとします。それを機能させるためには、自分自身のためのフィルタとしてオブジェクト(具体的にはウィジェット)をインストールする必要があります。ウィジェットが作成された後にそれを行う必要があります。したがって、MyActionコンストラクタにfilterをインストールすると、早すぎてクラッシュする可能性があります。フィルターインストールのためのより良い場所は、MyActionオブジェクトを所有するクラスのコンストラクターです。通常はウィジェットまたはウィンドウクラスです。したがって、ui->setupUi(this)コールの後にウィンドウコンストラクタに

for(auto wgtPtr : ui->myActionObject->associatedWidgets()) { 
    wgtPtr->installEventFilter(ui->myActionObject); 
} 

を追加するだけです。このコードは上記の例のようですが、thisオブジェクトの代わりにui->myActionObjectオブジェクトをフィルタとして使用します。

+0

QActionとして使用するクラスIでeventFilterを作成できますか?私はすでにQActionから継承したクラスを持っており、私はそれを私のアプリケーションで使っています。私はeventFilterメソッドをオーバーライドしましたが、何も起こっていません。どこかにインストールする必要がありますか? –

+0

@Slousousできることは確かです。私はあなたのコードを動作させるはずの私の答えからケース2の明確化を追加しました。 'eventFilter'メソッドから' qDebug() 'に何かを印刷して、正しく動作することを確認してください。 – Sergey

+0

これは 'QSystemTrayIcon'で使用したいときに使えますか?私のアプリケーションにはGUIはなく、 'QSystemTrayIcon'には' QActions'しかありません。 –

3

triggered()は、設計により、この引数を持つことができない。

アクションがユーザによって起動されると、この信号が発せられます。ユーザーは、をメニューオプション、ツールバーのボタンをクリックするか、アクションのショートカットキーの組み合わせを押す、またはトリガ()が呼び出された場合など、ために

あなたは、パラメータとしてQMouseEventが必要な場合は、マウスイベントに接続する必要があります。実際、Qt自体はtriggered()を発行します(ただし、doc quoteで強調されただけではありません)。フレームワークはメニューからマウスイベントを受け取ります。だからあなたのコードで同様のことをして、独自のロジックを追加する必要があるように見えます。

P.S. This discussionがおもしろいかもしれません。

関連する問題