у меня есть QAction
в QMenu
, когда QAction
является triggered()
Я хотел бы знать, какая кнопка сделала это.
connect(YourAction, SIGNAL(triggered()), this, SLOT(actionclicked()));
void MainWindow::actionclicked(QMouseEvent *e)
{
if (e->buttons() == Qt::RightButton)
}
Я не могу сделать что-то подобное, потому что triggered()
не имеет такого аргумента.
Как заметил @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
метод. В реальном коде вы можете:
QObject
подкласс (ы) для QAction
фильтрация событий виджетов.QAction
и переопределить это eventFilter
метод. В этом случае вы можете просто сохранить результат QMouseEvent::button()
в QAction
объект подкласса, а затем использовать его в triggered()
обработчик сигнала. Есть небольшое неудобство, что создатель Qt (по крайней мере, до версии 3.2.1) не позволяет вам «продвигать» QAction
Он находится в конструкторе форм, поэтому вам нужно добавить действия к меню вручную в конструкторе окон.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
объект как фильтр.
triggered()
не может иметь этот аргумент по своему замыслу, потому что сам по себе он не обязательно является результатом события мыши:
Этот сигнал испускается, когда действие активируется пользователем; например, когда пользователь щелкает пункт меню, кнопку панели инструментов, или нажимает комбинацию горячих клавиш действия, или когда вызывался триггер ()
Вам нужно подключиться к событиям мыши, если вам нужно QMouseEvent
в качестве параметра. На самом деле сам Qt излучает triggered()
когда (но не только как я выделил в цитате документа) фреймворк получает событие мыши из меню. Похоже, что вам нужно сделать что-то подобное в вашем коде и добавить собственную логику.
Постскриптум Это обсуждение может быть интересным для вас