Я хочу знать, нажата ли 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) не позволяет вам "продвигать"QAction
s в дизайнере форм, поэтому вам нужно будет добавить действия в меню вручную в окне конструктор. - подкласс
QMenu
,QToolBar
, etc.., и сделать их фильтрами действий? Я не знаю, как это может быть лучше, чем два предыдущих варианта.
см. также документация о системе событий Qt.
давайте проясним случай 2. Предположим, что класс унаследован от QAction
называется MyAction
. Чтобы заставить его работать, вам нужно установить MyAction
объекты в качестве фильтров для себя (их виджеты, чтобы быть более конкретными). Вам нужно сделать это после того, как виджеты были созданы, поэтому установка фильтра в MyAction
конструктор может быть преждевременным и привести к сбоям. Лучшим местом для установки фильтра является конструктор класса, которому принадлежит
triggered()
не может быть, этот аргумент, поскольку он сам по себе не обязательно является результатом события мыши:
этот сигнал испускается, когда действие активируется пользователем; например, когда пользователь нажимает кнопку меню, Панель инструментов,или нажимает комбинацию клавиш быстрого доступа действия, или когда trigger () был вызван
вам нужно подключиться к событиям мыши, Если вам нужно QMouseEvent
в качестве параметра. На самом деле Qt сам излучает triggered()
когда (но не только, как я выделил в цитате doc) framework получает событие мыши из меню. Таким образом, похоже, вам нужно будет сделать аналогичную вещь в своем коде и добавить свою собственную логику.
П. С. эта дискуссия может быть интересно для вас