Рассмотрим пример создания виджета с контекстным меню. Начнем с заголовочного файла:
#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(), которая в качестве аргумента принимает координаты, относительно которых меню должно быть выведено на экран.
В результате у нас получилось вот такое приложение, из которого можно выйти с помощью контекстного меню: