Я хочу знать, нажата ли QAction левой или правой кнопкой мыши
у меня есть QAction на QMenu. Когда QAction is triggered() Я хотел бы знать, какая кнопка это сделал.
connect(YourAction, SIGNAL(triggered()), this, SLOT(actionclicked()));
void MainWindow::actionclicked(QMouseEvent *e)
{
if (e->buttons() == Qt::RightButton)
}
Я не могу сделать что-то подобное, потому что triggered() нет такого аргумента.
2 ответов
как заметил @mvidelgauz,QAction абстрагируется от устройств ввода, которые могут инициировать действие. Тем не менее, если действие используется в вашем GUI, оно имеет один или несколько связанных виджетов: кнопки инструментов на панели инструментов, записи в строке меню и так далее. Эти виджеты действуют как любые другие виджеты, поэтому они получают события, которые могут быть отфильтрованы с использованием 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 метод. В реальном коде вы можете либо:
- создать посвящается
QObjectподкласс(ы)QActionфильтрация событий виджетов. - подкласс
QActionи переопределить этоeventFilterметод. В этом случае вы можете просто сохранить результатQMouseEvent::button()наQActionобъект подкласса и позже использовать его вtriggered()обработчик сигнала. Существует небольшое неудобство, что Qt creator (по крайней мере, до v3.2.1) не позволяет вам "продвигать"QActions в дизайнере форм, поэтому вам нужно будет добавить действия в меню вручную в окне конструктор. - подкласс
QMenu,QToolBar, etc.., и сделать их фильтрами действий? Я не знаю, как это может быть лучше, чем два предыдущих варианта.
см. также документация о системе событий Qt.
давайте проясним случай 2. Предположим, что класс унаследован от QAction называется MyAction. Чтобы заставить его работать, вам нужно установить MyAction объекты в качестве фильтров для себя (их виджеты, чтобы быть более конкретными). Вам нужно сделать это после того, как виджеты были созданы, поэтому установка фильтра в MyAction конструктор может быть преждевременным и привести к сбоям. Лучшим местом для установки фильтра является конструктор класса, которому принадлежит
triggered() не может быть, этот аргумент, поскольку он сам по себе не обязательно является результатом события мыши:
этот сигнал испускается, когда действие активируется пользователем; например, когда пользователь нажимает кнопку меню, Панель инструментов,или нажимает комбинацию клавиш быстрого доступа действия, или когда trigger () был вызван
вам нужно подключиться к событиям мыши, Если вам нужно QMouseEvent в качестве параметра. На самом деле Qt сам излучает triggered() когда (но не только, как я выделил в цитате doc) framework получает событие мыши из меню. Таким образом, похоже, вам нужно будет сделать аналогичную вещь в своем коде и добавить свою собственную логику.
П. С. эта дискуссия может быть интересно для вас