@mvidelgauzに告知されているように、入力デバイスからは、アクションを引き起こす可能性のある入力デバイスから抽象化されています。それにもかかわらず、あなたのGUIでアクションが使用されている場合は、ツールバーのツールボタン、メニューバーの項目など、関連付けられたウィジェットが1つ以上あります。これらのウィジェットは他のウィジェットと同じように動作し、installEventFilterとeventFilterを使用してフィルタリングされる可能性のあるイベントを受け取ります。これらの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
メソッドをホストするのに最適な場所ではありません。あなたはどちらかかもしれない実際のコードでは:
QAction
ウィジェットイベントのフィルタリングのための専用QObject
サブクラス(複数可)を作成します。
- サブクラス
QAction
をオーバーライドし、eventFilter
メソッドをオーバーライドします。この場合、QMouseEvent::button()
の結果をQAction
サブクラスオブジェクトに保存し、後でtriggered()
シグナルハンドラで使用することができます。 Qtの作成者(少なくともv3.2.1まで)は、フォームデザイナーでQAction
を "昇進"させないため、ウィンドウコンストラクターでメニューに手動でアクションを追加する必要があります。
- サブクラス
QMenu
、QToolBar
など、アクションフィルタを作成しますか?私はそれが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
オブジェクトをフィルタとして使用します。
QActionとして使用するクラスIでeventFilterを作成できますか?私はすでにQActionから継承したクラスを持っており、私はそれを私のアプリケーションで使っています。私はeventFilterメソッドをオーバーライドしましたが、何も起こっていません。どこかにインストールする必要がありますか? –
@Slousousできることは確かです。私はあなたのコードを動作させるはずの私の答えからケース2の明確化を追加しました。 'eventFilter'メソッドから' qDebug() 'に何かを印刷して、正しく動作することを確認してください。 – Sergey
これは 'QSystemTrayIcon'で使用したいときに使えますか?私のアプリケーションにはGUIはなく、 'QSystemTrayIcon'には' QActions'しかありません。 –