当前位置: 首页 > news >正文

【十六】【QT开发应用】Menu菜单,contextMenuEvent,setContextMenuPolicy,addAction

在 Qt 框架中,QMenu 类用于创建和管理菜单。菜单是用户界面的一部分,可以包含多个选项或动作,用户可以选择这些选项来执行特定的功能。菜单通常显示在菜单栏、上下文菜单(右键菜单)或工具栏中。
基本用法

创建菜单对象:

QMenu *menu = new QMenu(this); // 创建一个新的 QMenu 对象,父对象为当前小部件

添加动作:
使用 addAction 方法将 QAction 对象添加到菜单中。QAction 代表菜单中的一个选项或动作。

QAction *action1 = new QAction("Action 1", this);
menu->addAction(action1); // 将动作添加到菜单

显示菜单:
菜单可以在指定的位置显示,例如在鼠标光标位置。

menu->exec(QCursor::pos()); // 在当前光标位置显示菜单

在这里插入图片描述

widget.h

#pragma once#include <QtWidgets/QWidget>
#include "ui_widget.h"
#include <QMenu>class widget : public QWidget
{Q_OBJECTpublic:widget(QWidget *parent = nullptr);~widget();void contextMenuEvent(QContextMenuEvent* event) override;void initMenu();private:Ui::widgetClass ui;QMenu* m_pMenu = nullptr;
};

widget.cpp

#include "widget.h"
#include <QAction>
#include <QMessageBox>widget::widget(QWidget *parent): QWidget(parent)
{ui.setupUi(this);this->setContextMenuPolicy(Qt::DefaultContextMenu);initMenu();
}widget::~widget()
{}void widget::contextMenuEvent(QContextMenuEvent* event) {m_pMenu->exec(QCursor::pos());
}void widget::initMenu() {m_pMenu = new QMenu(this);QAction* pAc1 = new QAction("ac1");QAction* pAc2 = new QAction("ac2");QAction* pAc3 = new QAction("ac3");QAction* pAc4 = new QAction("ac4");QAction* pAc5 = new QAction("ac5");QAction* pAc6 = new QAction("ac6");QAction* pAc7 = new QAction("ac7");m_pMenu->addAction(pAc1);m_pMenu->addAction(pAc2);m_pMenu->addAction(pAc3);m_pMenu->addAction(pAc4);m_pMenu->addAction(pAc5);m_pMenu->addAction(pAc6);m_pMenu->addAction(pAc7);connect(pAc1, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac1");});connect(pAc2, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac2");});connect(pAc3, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac3");});connect(pAc4, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac4");});connect(pAc5, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac5");});connect(pAc6, &QAction::trigger, [=] {QMessageBox::information(this, "title", "ac6");});connect(pAc7, &QAction::trigger, [=] {QMessageBox::information(this, "title", "ac7");});
}

复盘

#include "widget.h"
#include <QAction>
#include <QMessageBox>widget::widget(QWidget *parent): QWidget(parent)
{ui.setupUi(this);// 设置上下文菜单策略为默认this->setContextMenuPolicy(Qt::DefaultContextMenu);initMenu(); // 初始化菜单
}widget::~widget()
{}void widget::contextMenuEvent(QContextMenuEvent* event) {m_pMenu->exec(QCursor::pos()); // 在光标位置执行菜单
}void widget::initMenu() {m_pMenu = new QMenu(this); // 创建新的QMenuQAction* pAc1 = new QAction("ac1"); // 创建动作ac1QAction* pAc2 = new QAction("ac2"); // 创建动作ac2QAction* pAc3 = new QAction("ac3"); // 创建动作ac3QAction* pAc4 = new QAction("ac4"); // 创建动作ac4QAction* pAc5 = new QAction("ac5"); // 创建动作ac5QAction* pAc6 = new QAction("ac6"); // 创建动作ac6QAction* pAc7 = new QAction("ac7"); // 创建动作ac7m_pMenu->addAction(pAc1); // 将动作ac1添加到菜单m_pMenu->addAction(pAc2); // 将动作ac2添加到菜单m_pMenu->addAction(pAc3); // 将动作ac3添加到菜单m_pMenu->addAction(pAc4); // 将动作ac4添加到菜单m_pMenu->addAction(pAc5); // 将动作ac5添加到菜单m_pMenu->addAction(pAc6); // 将动作ac6添加到菜单m_pMenu->addAction(pAc7); // 将动作ac7添加到菜单// 连接动作ac1的触发信号到槽函数,显示信息框connect(pAc1, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac1");});// 连接动作ac2的触发信号到槽函数,显示信息框connect(pAc2, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac2");});// 连接动作ac3的触发信号到槽函数,显示信息框connect(pAc3, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac3");});// 连接动作ac4的触发信号到槽函数,显示信息框connect(pAc4, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac4");});// 连接动作ac5的触发信号到槽函数,显示信息框connect(pAc5, &QAction::triggered, [=] {QMessageBox::information(this, "title", "ac5");});// 连接动作ac6的触发信号到槽函数,显示信息框connect(pAc6, &QAction::trigger, [=] {QMessageBox::information(this, "title", "ac6");});// 连接动作ac7的触发信号到槽函数,显示信息框connect(pAc7, &QAction::trigger, [=] {QMessageBox::information(this, "title", "ac7");});
}

setContextMenuPolicy

setContextMenuPolicy 是 Qt 中 QWidget 类的一个函数,用于设置小部件的上下文菜单策略。上下文菜单(也称为右键菜单)是用户通过右键单击触发的菜单。
Qt::ContextMenuPolicy 枚举定义了以下几种策略:

Qt::NoContextMenu: 禁用上下文菜单。

Qt::PreventContextMenu: 禁用默认上下文菜单,但仍然会触发 contextMenuEvent。

Qt::DefaultContextMenu: 使用 QWidget 的默认上下文菜单处理。

Qt::ActionsContextMenu: 显示与 QWidget 关联的动作(QAction)。

Qt::CustomContextMenu: 触发 customContextMenuRequested 信号,用户可以连接自己的槽函数来处理。

this->setContextMenuPolicy(Qt::DefaultContextMenu);

设置了默认的上下文菜单策略,即当用户右键单击小部件时,会触发 contextMenuEvent 函数。你可以在这个事件处理函数中自定义上下文菜单的行为,如下所示:

void widget::contextMenuEvent(QContextMenuEvent* event) {m_pMenu->exec(QCursor::pos()); // 在光标位置显示菜单
}

通过这个设置,你可以为小部件提供自定义的上下文菜单,而不是依赖于系统的默认菜单。

QAction 和 QMenu

QAction 和 QMenu 是 Qt 框架中用于创建和管理菜单项的类。

QAction* pAc1 = new QAction("ac1");

这行代码创建了一个新的 QAction 对象。QAction 表示一个动作,可以被用户在菜单、工具栏或快捷键中触发。构造函数接受一个字符串参数作为动作的文本标签。

QAction 构造函数: QAction(const QString &text, QObject *parent = nullptr)

text: 动作的标签文本。在这个例子中,标签是 “ac1”。

parent: 动作的父对象。这里没有指定父对象,默认值为 nullptr。

QAction* pAc1 = new QAction("ac1"); // 创建一个标签为“ac1”的新动作m_pMenu->addAction(pAc1);

这行代码将先前创建的 QAction 对象 pAc1 添加到菜单 m_pMenu 中。QMenu 是 Qt 中用于创建菜单的类,addAction 函数用于向菜单中添加一个动作。

QMenu 函数: void addAction(QAction *action)

action: 要添加到菜单中的 QAction 对象。

m_pMenu->exec(QCursor::pos());

m_pMenu->exec(QCursor::pos()); 是在 Qt 中显示上下文菜单的一种常见方式。

m_pMenu->exec(QCursor::pos());

m_pMenu:这是一个 QMenu 对象的指针,表示要显示的菜单。

exec():QMenu 类的成员函数,用于以模态方式显示菜单,并阻塞直到用户选择了菜单项或关闭了菜单。exec() 函数返回用户选择的 QAction 指针,如果用户没有选择任何项而是关闭了菜单,则返回 nullptr。

QCursor::pos():静态函数,返回当前鼠标光标的位置(以全局坐标系表示)。通过这个位置,可以在鼠标光标处显示菜单。

在上下文菜单事件中,我们通常会使用这行代码来显示上下文菜单:

void widget::contextMenuEvent(QContextMenuEvent* event) {m_pMenu->exec(QCursor::pos()); // 在光标位置显示菜单
}

显示菜单:exec() 方法会在指定位置显示菜单。在这个例子中,QCursor::pos() 返回当前光标的位置,因此菜单会在鼠标光标处弹出。

阻塞调用:exec() 是一个阻塞调用,这意味着程序执行会暂停在这一行,直到用户在菜单中选择一个动作或关闭菜单。然后,exec() 将返回选择的 QAction 或 nullptr。

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!

相关文章:

【十六】【QT开发应用】Menu菜单,contextMenuEvent,setContextMenuPolicy,addAction

在 Qt 框架中&#xff0c;QMenu 类用于创建和管理菜单。菜单是用户界面的一部分&#xff0c;可以包含多个选项或动作&#xff0c;用户可以选择这些选项来执行特定的功能。菜单通常显示在菜单栏、上下文菜单&#xff08;右键菜单&#xff09;或工具栏中。 基本用法 创建菜单对象…...

华为DCN技术:M-LAG

M-LAG&#xff08;Multichassis Link Aggregation Group&#xff09;即跨设备链路聚合组&#xff0c;是一种实现跨设备链路聚合的机制。M-LAG主要应用于普通以太网络、VXLAN和IP网络的双归接入&#xff0c;可以起到负载分担或备份保护的作用。相较于另一种常见的可靠性接入技术…...

k8s持久化之emptyDir使用

目录 概述实践代码 概述 理解emptyDir使用&#xff0c;是后续k8s持久化进阶&#xff0c;高阶使用的基础。 实践 代码 详细说明在代码中 # 缓存数据&#xff0c;可以让多个容器共享数据 # 删除 Pod 时&#xff0c;emptyDir 数据同步消失 # 定义 initContainer -> 下载数据…...

Java露营基地预约小程序预约下单系统源码

轻松开启户外探险之旅 &#x1f31f; 露营热潮来袭&#xff0c;你准备好了吗&#xff1f; 随着人们对户外生活的热爱日益增加&#xff0c;露营已成为许多人周末和假期的首选活动。但你是否曾因找不到合适的露营基地而烦恼&#xff1f;或是因为繁琐的预约流程而错失心仪的营地…...

七天速通javaSE:第四天 java方法

文章目录 前言一、什么是方法&#xff1f;二、方法的定义与调用1. 方法的定义2. 方法的调用3. 练习&#xff1a;定义比大小方法并调用 三、方法的重载四、递归五、可变参数拓展&#xff1a;命令行传递参数 前言 本章将学习java方法。 一、什么是方法&#xff1f; java方法是用…...

jupyter notebook的markdown语法不起作用

在这个界面编辑&#xff0c;发现markdown你编辑的是什么就是什么&#xff0c;不起作用&#xff0c;然而点一下&#xff1a; 右上角“Notebook转发”&#xff0c;就会单独跳出一个jupyter notebook的界面&#xff0c;此时就会奏效&#xff1a;...

Redis 学习笔记(2)

目录 1 Redis的持久化1.1 RDB持久化方案1.2 AOF持久化方案 2 Redis架构2.1 主从复制架构2.2 哨兵集群设计2.3 哨兵集群设计 3 Redis事务机制4 Redis过期策略与内存淘汰机制4.1 过期策略4.2 内存淘汰机制 5 Redis高频面试题4.1 缓存穿透4.2 缓存击穿4.3 缓存雪崩 1 Redis的持久化…...

快慢指针:删除有序数组中的重复项

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路好想&#xff0c;代码实现不好想 class Solution {public int removeDuplicates(int[] nums) {int fast 1,slow 1;while(fast < nums.length){if(nums[fast] ! nums[fast-1]){nums[slow] nums[fast]…...

用户登录错误次数太多锁定账号

当用户登录验证码错误次数太多时&#xff0c;需要限制用户在10分钟之内不能再次登录。 限制方案&#xff1a; 1.通过Redis ZSet key可以设置为用户名&#xff0c;value可以设置为UUID&#xff0c;score设置为当前时间戳 每次用户登录时&#xff0c;通过 rangeByScore 查询对…...

tedsign vue3 web-端框架中封装一个验证码组件 以及对应node 接口逻辑说明

一个这样的组件 我直接上代码了 <template><t-loading size"small" :loading"loading" show-overlay><div class"container" click"refresh"><div v-if"svg" class"svg" v-html"svg&…...

探索Scala并发编程之巅:高效并行处理的艺术

标题&#xff1a;探索Scala并发编程之巅&#xff1a;高效并行处理的艺术 引言 在现代软件开发中&#xff0c;随着多核处理器的普及&#xff0c;编写能够充分利用硬件能力的并发程序变得至关重要。Scala&#xff0c;这门结合了面向对象和函数式编程特性的语言&#xff0c;提供…...

AudioLM: 音频生成的革命性模型

AudioLM: 音频生成的革命性模型 AudioLM是一种革命性的音频生成模型&#xff0c;它结合了深度学习和自然语言处理的先进技术&#xff0c;能够生成高质量、逼真的音频内容。本文将探讨AudioLM的基本原理、工作机制、应用场景以及对音频生成领域的影响和未来发展方向。 一、Aud…...

C++ Vector的模拟实现

vector的介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以动态改变的&#xff0c;而…...

Kubernetes之Controller详解

本文尝试从Kubernetes Controller的种类、交互逻辑、最佳实践、伪代码示例及历史演进5个方面对其进行详细阐述&#xff0c;希望对您有所帮助&#xff01; 一、Kubernetes Controller种类 Kubernetes Controller Manager 是 Kubernetes 集群的核心组件之一&#xff0c;负责管理…...

openlayers性能优化——开启图层预加载、减少空白等待时间

使用切片图层时、地图拖拽会有空白图片&#xff0c;为了减少空白等待时间&#xff0c;我们可以开始图层预加载。 const map_top new Map({layers: [new TileLayer({preload:Infinity, //预加载source: new StadiaMaps({layer: "outdoors",}),}),],target: "ma…...

BlockingQueue详解(含动画演示)

目录 BlockingQueue详解0、BlockingQueue简介BlockingQueue接口中方法注释BlockingQueue的实现&#xff0c;总结计划 1、ArrayBlockingQueue简介2、ArrayBlockingQueue的继承体系3、ArrayBlockingQueue的构造方法①、 ArrayBlockingQueue(int capacity)②、ArrayBlockingQueue(…...

wordpress商用付费主题与免费主题的区别

WordPress免费主题与WordPress付费主题&#xff0c;都可以用&#xff0c;但存在非常大的差别。从直观的感受&#xff0c;简单地说就是&#xff0c;WordPress免费主题能用&#xff0c;WordPress付费主题好用。如果涉及到其它的方面&#xff0c;WordPress商用付费主题与免费主题之…...

【ARM Trace32(劳特巴赫) 使用介绍 2.7 -- bat 脚本传参数给 trace32 cmm 脚本】

请阅读【Trace32 ARM 专栏导读】 文章目录 bat 脚本传参数给 trace32脚本可变参数传入CMM 脚本接收参数运行BAT脚本bat 脚本传参数给 trace32脚本 在使用 Trace32 的过程中,如果每次都是通过GUI 界面来操作,是习惯使用命令行工作的人所不能忍受的!!!,那么能不同通过脚本…...

NavicatforMySQL11.0软件下载-NavicatMySQL11最新版下载附件详细安装步骤

我们必须承认Navicat for MySQL 支援 Unicode&#xff0c;以及本地或远程 MySQL 服务器多连线&#xff0c;使用者可浏览数据库、建立和删除数据库、编辑数据、建立或执行 SQL queries、管理使用者权限&#xff08;安全设定&#xff09;、将数据库备份/复原、汇入/汇出数据&…...

弱监督学习

弱监督学习&#xff08;Weak Supervision&#xff09;是一种利用不完全、不精确或噪声数据进行模型训练的方法。以下是一些常用的弱监督方法及其原理&#xff1a; 1. 数据增强&#xff08;Data Augmentation&#xff09; 原理&#xff1a; 数据增强是一种通过增加训练数据的多…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python&#xff5c;GIF 解析与构建&#xff08;5&#xff09;&#xff1a;手搓截屏和帧率控制 一、引言 二、技术实现&#xff1a;手搓截屏模块 2.1 核心原理 2.2 代码解析&#xff1a;ScreenshotData类 2.2.1 截图函数&#xff1a;capture_screen 三、技术实现&…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...