Рассмотрим пример создания виджета с контекстным меню. Начнем с заголовочного файла:
#ifndef CONTEXTMENUDEMO_H
#define CONTEXTMENUDEMO_H
#include <QWidget>
class QMenu;
class ContextMenuDemo : public QWidget {
Q_OBJECT
public:
ContextMenuDemo( QWidget* parent = 0 );
~ContextMenuDemo();
protected:
void contextMenuEvent( QContextMenuEvent* e );
private:
QMenu* m_menu;
};
#endif // CONTEXTMENUDEMO_H
Контекстное меню представлено полем m_menu
, которое является экземпляром класса QMenu
. Непосредственная обработка щелчка правой кнопки мыши по форме виджета происходит в защищенной виртуальной функции-члене contextMenuEvent()
базового класса QWidget
, которую мы переопределяем. Это означает, что контекстное меню будет привязано именно к этому виджету ContextMenuDemo
.
Переходим к соответствующему файлу реализации:
#include "contextmenudemo.h"
#include <QApplication>
#include <QContextMenuEvent>
#include <QMenu>
ContextMenuDemo::ContextMenuDemo( QWidget* parent )
: QWidget( parent ) {
m_menu = new QMenu( this );
QAction* exitAction = m_menu->addAction( "Exit" );
connect( exitAction, SIGNAL( triggered() ), qApp, SLOT( quit() ) );
}
ContextMenuDemo::~ContextMenuDemo() {
}
void ContextMenuDemo::contextMenuEvent( QContextMenuEvent* e ) {
if( m_menu ) {
m_menu->exec( e->globalPos() );
}
}
Добавление пункта к контекстному меню осуществляется с помощью addAction()
. На вход эта функция-член принимает строку с текстом, который соответствует названию этого пункта. Вместе с текстом вы можете передать иконку QIcon
, которая будет отображаться рядом с надписью. Аналогичным образом вы можете добавить столько пунктов, сколько понадобится. В этом смысле меню работает по принципу паттерна Строитель (см. Паттерн Строитель и XML).
В простейшем случае для обработки сигнала нажатия на пункт меню вы можете соединить сигнал triggered()
объекта QAction
с произвольным слотом. В представленном выше примере при нажатии на пункт меню Exit
будет вызван слот quit()
приложения qApp
, который приведет к завершению работы программы.
Также не забудьте про реализацию contextMenuEvent()
, иначе меню не появится. Для отображения контекстного меню достаточно вызвать функцию-член exec()
, которая в качестве аргумента принимает координаты, относительно которых меню должно быть выведено на экран.
В результате у нас получилось вот такое приложение, из которого можно выйти с помощью контекстного меню: