Я хочу знать, нажата ли QAction левой или правой кнопкой мыши

у меня есть QAction в QMenu, когда QAction является triggered() Я хотел бы знать, какая кнопка сделала это.

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

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

Я не могу сделать что-то подобное, потому что triggered() не имеет такого аргумента.

7

Решение

Как заметил @mvidelgauz, QAction абстрагируется от устройств ввода, которые могут вызвать действие. Тем не менее, если действие используется в вашем графическом интерфейсе, оно имеет один или несколько связанных виджетов: кнопки инструментов на панели инструментов, записи в строке меню и т. Д. Эти виджеты действуют как любые другие виджеты, поэтому они получают события, которые могут быть отфильтрованы с использованием installEventFilter а также eventFilter. Эти два метода унаследованы от 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 (по крайней мере, до версии 3.2.1) не позволяет вам «продвигать» QActionОн находится в конструкторе форм, поэтому вам нужно добавить действия к меню вручную в конструкторе окон.
  3. Подкласс QMenu, QToolBarи т. д., и сделать их фильтрами действий? Я не знаю, как это может быть лучше, чем два предыдущих варианта.

Смотрите также документация о системе событий Qt.

Давайте проясним случай 2. Предположим, что класс унаследован от QAction называется MyAction, Для того, чтобы это работало, вам нужно установить MyAction объекты как фильтры для себя (их виджеты, если быть более точными). Это необходимо сделать после создания виджетов, поэтому установите фильтр в MyAction Конструктор может быть преждевременным и привести к сбоям. Лучшее место для установки фильтра — конструктор класса, которому принадлежит MyAction объект. Обычно это виджет или класс окна. Так что просто добавьте

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

к вашему оконному конструктору после ui->setupUi(this) вызов. Этот код похож на приведенный выше пример, но мы используем ui->myActionObject вместо this объект как фильтр.

4

Другие решения

triggered() не может иметь этот аргумент по своему замыслу, потому что сам по себе он не обязательно является результатом события мыши:

Этот сигнал испускается, когда действие активируется пользователем; например, когда пользователь щелкает пункт меню, кнопку панели инструментов, или нажимает комбинацию горячих клавиш действия, или когда вызывался триггер ()

Вам нужно подключиться к событиям мыши, если вам нужно QMouseEvent в качестве параметра. На самом деле сам Qt излучает triggered() когда (но не только как я выделил в цитате документа) фреймворк получает событие мыши из меню. Похоже, что вам нужно сделать что-то подобное в вашем коде и добавить собственную логику.

Постскриптум Это обсуждение может быть интересным для вас

3

По вопросам рекламы [email protected]