[QT] Qt右键菜单的实现介绍与代码演示
某些软件需要实现右键菜单, 如下:
新建一个Qt GUI 程序,头文件代码如下:
*.h 代码
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_RightMenu.h"
class RightMenu : public QMainWindow
{
Q_OBJECT
public:
RightMenu(QWidget *parent = Q_NULLPTR);
void contextMenuEvent(QContextMenuEvent *event) override;
void keyPressEvent(QKeyEvent *e) override;
private slots:
void onAc1();
private:
Ui::RightMenuClass ui;
};
可以添加快捷键, 分割线, 在点击的同时, 又可以用快捷键操作
实现起来亦不难, 重写contextMenuEvent
方法, 该方法如下
[virtual protected] void QWidget::contextMenuEvent(QContextMenuEvent* event)
/// This event handler, for event event, can be reimplemented in a subclass to receive widget context menu events.
重写 contextMenuEvent
, 实现右键菜单, keyPressEvent
实现组合键
cpp代码
#include "RightMenu.h"
#include <QAction>
#include <QMenu>
#include <QMessageBox>
#include <QKeyEvent>
RightMenu::RightMenu(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
void RightMenu::contextMenuEvent(QContextMenuEvent *event)
{
QMenu *pMenu = new QMenu(this);
QAction *pAc1 = new QAction(QString::fromLocal8Bit("复制"), this);
pAc1->setShortcut(QKeySequence("Ctrl+C"));
QAction *pAc2 = new QAction(QString::fromLocal8Bit("粘贴"), this);
QAction *pAc3 = new QAction(QString::fromLocal8Bit("删除"), this);
pAc3->setShortcut(QKeySequence("Ctrl+D"));
QAction *pAc4 = new QAction(QString::fromLocal8Bit("刷新"), this);
pAc4->setShortcut(QKeySequence("Alt+F5"));
QAction *pAc5 = new QAction(QString::fromLocal8Bit("压缩"), this);
QAction *pAc6 = new QAction(QString::fromLocal8Bit("合并"), this);
QAction *pAc7 = new QAction(QString::fromLocal8Bit("发送"), this);
pAc7->setShortcut(QKeySequence("Ctrl+Shift+S"));
QAction *pAc8 = new QAction(QString::fromLocal8Bit("加密"), this);
pMenu->addAction(pAc1);
pMenu->addAction(pAc2);
pMenu->addAction(pAc3);
pMenu->addAction(pAc4);
pMenu->addSeparator();
pMenu->addAction(pAc5);
pMenu->addAction(pAc6);
pMenu->addSeparator();
pMenu->addAction(pAc7);
pMenu->addSeparator();
pMenu->addAction(pAc8);
pMenu->addSeparator();
pMenu->setStyleSheet("QMenu{font:18px;}");
pMenu->move(cursor().pos());
pMenu->show();
connect(pAc1, &QAction::triggered, this, &RightMenu::onAc1);
}
void RightMenu::keyPressEvent(QKeyEvent * e)
{
if (e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_C)
{
QMessageBox::information(this, "title", "you clicked Ac1 Copy");
}
if (e->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier) && e->key() == Qt::Key_S)
{
QMessageBox::information(this, "title", "you clicked Ac7 Send");
}
}
void RightMenu::onAc1()
{
QMessageBox::information(this, "title", "you clicked Ac1");
}
/// 设置快捷键 `
pAc1->setShortcut(QKeySequence("Ctrl + C"));
/// 设置菜单分割线
pMenu->addSeparator();
/// 菜单项的响应, 链接· triggered · 信号即可
/// 默认的右键菜单字体较小 可以使用样式表进行设置
pMenu->setStyleSheet("QMenu{front: 18px;}");
/// 在 · keyPressEvent · 中写各种快捷键的功能, 也可以使用时间过滤器 实现 方法很多
也可以添加子菜单, 例如下图:
只要稍微修改代码即可实现, 如下所示:
void RightMenu::contextMenuEvent(QContextMenuEvent *event)
{
QMenu *pMenu = new QMenu(this);
QMenu *pSubMenu = new QMenu(QString::fromLocal8Bit("文本操作"));
QAction *pAc1 = new QAction(QString::fromLocal8Bit("复制"), this);
pAc1->setShortcut(QKeySequence("Ctrl+C"));
QAction *pAc2 = new QAction(QString::fromLocal8Bit("粘贴"), this);
QAction *pAc3 = new QAction(QString::fromLocal8Bit("删除"), this);
pAc3->setShortcut(QKeySequence("Ctrl+D"));
QAction *pAc4 = new QAction(QString::fromLocal8Bit("刷新"), this);
pAc4->setShortcut(QKeySequence("Alt+F5"));
QAction *pAc5 = new QAction(QString::fromLocal8Bit("压缩"), this);
QAction *pAc6 = new QAction(QString::fromLocal8Bit("合并"), this);
QAction *pAc7 = new QAction(QString::fromLocal8Bit("发送"), this);
pAc7->setShortcut(QKeySequence("Ctrl+Shift+S"));
QAction *pAc8 = new QAction(QString::fromLocal8Bit("加密"), this);
pSubMenu->addAction(pAc1);
pSubMenu->addAction(pAc2);
pSubMenu->addAction(pAc3);
pMenu->addMenu(pSubMenu); //主菜单添加子菜单
pMenu->addAction(pAc4);
pMenu->addSeparator();
pMenu->addAction(pAc5);
pMenu->addAction(pAc6);
pMenu->addSeparator();
pMenu->addAction(pAc7);
pMenu->addSeparator();
pMenu->addAction(pAc8);
pMenu->addSeparator();
pMenu->setStyleSheet("QMenu{font:18px;}");
pMenu->move(cursor().pos());
pMenu->show();
connect(pAc1, &QAction::triggered, this, &RightMenu::onAc1);
}
每个菜单项还可以添加图标,
explicit QAction(QObject *parent = nullptr);
explicit QAction(const QString &text, QObject *parent = nullptr);
explicit QAction(const QIcon &icon, const QString &text, QObject *parent = nullptr);