7

私は を持っていQActionますQMenu。いつどのボタンQActiontriggered()それをしたか知りたいです。

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

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

triggered()はそのような引数を持っていないため、このようなことはできません。

4

2 に答える 2

4

@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実際のコードでは、次のいずれかを実行できます。

  1. ウィジェット イベント フィルタリング専用QObjectのサブクラスを作成します。QAction
  2. メソッドをサブクラスQAction化してオーバーライドしますeventFilter。この場合、結果をサブクラス オブジェクトに保存しQMouseEvent::button()QAction後でtriggered()シグナル ハンドラで使用することができます。Qt クリエーター (少なくとも v3.2.1 まで) ではQAction、フォーム デザイナーで を "昇格" させることができないため、ウィンドウ コンストラクターで手動でメニューにアクションを追加する必要があります。
  3. 、などをサブクラス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フィルターとして使用します。

于 2016-08-06T13:48:09.840 に答える
3

triggered()設計上、この引数を持つことはできません。これは、それ自体がマウス イベントの結果であるとは限らないためです。

このシグナルは、アクションがユーザーによってアクティブ化されたときに発行されます。たとえば、ユーザーがメニュー オプション、ツールバー ボタンをクリックしたとき、アクションのショートカット キーの組み合わせを押したとき、または trigger() が呼び出されたときなどです。

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

PSこの議論はあなたにとって興味深いかもしれません

于 2016-08-06T12:05:09.613 に答える