一、QWidget自定义右键菜单
QWidget提供相关的接口可以设置自定义右键菜单,如下:
void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy)
枚举值 | 作用 |
---|---|
Qt::NoContextMenu | 本对象不显示右键菜单,由父对象决定 |
Qt::PreventContextMenu | 不显示右键菜单,与NoContentMenu不同,不向上层传递右键菜单的命令 |
Qt::DefaultContextMenu | 调用QWidget::contextMenuEvent(), 子类如果自定义菜单项需要重写这个虚函数 。(注意:该值是默认的属性值) |
Qt::ActionsContextMenu | 将本QWidget的所有QAction作为右键显示的菜单,这些QAction是通过QWidget::addActions方法添加的 |
Qt::CustomContextMenu | 发送信号QWidget::customContextMenuRequested(), 通过发信号的形式 |
下面通过一个示例介绍常用的几种策略的用法,如下:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QAction>
#define ACTION_MAX_SIZE 5
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_pMenu = nullptr;
m_pCustomMenu = nullptr;
ui->comboBox->addItem("Qt::DefaultContextMenu");
ui->comboBox->addItem("Qt::ActionsContextMenu");
ui->comboBox->addItem("Qt::CustomContextMenu");
// 方法一:给Widget添加右键菜单,如果右键菜单策略设置的是Qt::ActionsContextMenu,右键时会显示Widget所有的Actions
QList<QAction*> actionList;
for (int i = 0; i < ACTION_MAX_SIZE; i ++)
{
QAction *pAction = new QAction(this);
pAction->setText("ActionsContextMenu Action " + QString::number(i));
connect(pAction, SIGNAL(triggered(bool)), this, SLOT(OnAction()));
actionList.append(pAction);
}
// 调用QWidget::addActions方法添加QAction,当策略采用的是Qt::ActionsContextMenu,会显示添加的菜单
addActions(actionList);
connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnCurrentIndexChange(int)));
// 方法二:通过连接QWidget::customContextMenuRequested信号,实现右键菜单功能,当策略采用的是Qt::CustomContextMenu,会显示槽函数里面的菜单
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(OnShowMenu(const QPoint &)));
}
Widget::~Widget()
{
delete ui;
if (m_pMenu)
{
delete m_pMenu;
}
}
// 方法三:如果右键菜单策略选择的是Qt::DefaultContextMenu(默认的策略),QWidget的派生类通过实现虚函数contextMenuEvent
// 来弹出右键菜单
void Widget::contextMenuEvent(QContextMenuEvent *event)
{
if (m_pMenu == nullptr)
{
m_pMenu = new QMenu(this);
m_pMenu->setParent(this);
QList<QAction*> actionList;
for (int i = 0; i < ACTION_MAX_SIZE; i ++)
{
QAction *pAction = new QAction(this);
pAction->setText("DefaultContextMenu Action " + QString::number(i));
connect(pAction, SIGNAL(triggered(bool)), this, SLOT(OnAction()));
actionList.append(pAction);
}
m_pMenu->addActions(actionList);
}
m_pMenu->move(event->globalX() ,event->globalY());
m_pMenu->show();
}
void Widget::OnAction()
{
QObject *pObj = sender();
QAction *pAction = dynamic_cast<QAction*>(pObj);
qDebug() << "Clieck " << pAction->text();
}
void Widget::OnCurrentIndexChange(int index)
{
switch(index)
{
case 0:
setContextMenuPolicy(Qt::DefaultContextMenu);
ui->label->setText("MenuPolicy Qt::DefaultContextMenu");
break;
case 1:
setContextMenuPolicy(Qt::ActionsContextMenu);
ui->label->setText("Qt::ActionsContextMenu");
break;
case 2:
setContextMenuPolicy(Qt::CustomContextMenu);
ui->label->setText("Qt::CustomContextMenu");
break;
}
}
void Widget::OnShowMenu(const QPoint &pos)
{
if (m_pCustomMenu == nullptr)
{
m_pCustomMenu = new QMenu(this);
m_pCustomMenu->setParent(this);
QList<QAction*> actionList;
for (int i = 0; i < ACTION_MAX_SIZE; i ++)
{
QAction *pAction = new QAction(this);
pAction->setText("CustomContextMenu Action " + QString::number(i));
connect(pAction, SIGNAL(triggered(bool)), this, SLOT(OnAction()));
actionList.append(pAction);
}
m_pCustomMenu->addActions(actionList);
}
m_pCustomMenu->move(pos);
m_pCustomMenu->show();
}
运行结果