@mvidelgauz が気付いたようにQAction
、アクションをトリガーした可能性のある入力デバイスから抽象化されます。それにもかかわらず、アクションが GUI で使用される場合、1 つ以上の関連付けられたウィジェット (ツールバーのツール ボタン、メニュー バーのエントリなど) があります。これらのウィジェットは他のウィジェットと同様に機能するため、installEventFilterおよびeventFilterを使用してフィルタリングできるイベントを受け取ります。これら 2 つのメソッドは から継承されQObject
ているため、ほぼすべての Qt クラスに存在します。たとえば、QMainWindow と QAction という名前のアプリケーションを作成してみましょうactionTest
。次に、メイン ウィンドウのメソッドactionTest
をオーバーライドして、メイン ウィンドウ自体を の関連付けられたウィジェットのアクション フィルターに変えましょう。eventFilter
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
実際のコードでは、次のいずれかを実行できます。
- ウィジェット イベント フィルタリング専用
QObject
のサブクラスを作成します。QAction
- メソッドをサブクラス
QAction
化してオーバーライドしますeventFilter
。この場合、結果をサブクラス オブジェクトに保存しQMouseEvent::button()
、QAction
後でtriggered()
シグナル ハンドラで使用することができます。Qt クリエーター (少なくとも v3.2.1 まで) ではQAction
、フォーム デザイナーで を "昇格" させることができないため、ウィンドウ コンストラクターで手動でメニューにアクションを追加する必要があります。
- 、などをサブクラス
QMenu
化し、QToolBar
それらをアクション フィルターにしますか? 以前の 2 つのバリアントよりも優れているとは思えません。
Qt イベント システムに関するドキュメントも参照してください。
ケース 2 を明確にしましょう。継承元のクラスQAction
が と呼ばれているとしMyAction
ます。それを機能させるには、MyAction
オブジェクトをそれ自体のフィルターとしてインストールする必要があります (より具体的には、ウィジェット)。ウィジェットが作成された後に行う必要があるため、MyAction
コンストラクターにフィルターをインストールするのは時期尚早であり、クラッシュにつながる可能性があります。フィルターのインストールに適した場所は、MyAction
オブジェクトを所有するクラスのコンストラクターです。通常、これはウィジェットまたはウィンドウ クラスです。だから追加するだけ
for(auto wgtPtr : ui->myActionObject->associatedWidgets()) {
wgtPtr->installEventFilter(ui->myActionObject);
}
ui->setupUi(this)
呼び出し後にウィンドウコンストラクターに。このコードは上記の例と似ていますが、オブジェクトui->myActionObject
の代わりにthis
フィルターとして使用します。