当前位置: 首页 > 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; 数据增强是一种通过增加训练数据的多…...

为什么你的Midjourney账单暴涨200%?3个被官方文档隐瞒的计费临界点曝光(含--tile模式下的隐性显存倍增机制)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Midjourney GPU时间计算的本质与计费范式重构 Midjourney 的 GPU 时间并非基于物理设备的实时秒级占用&#xff0c;而是通过抽象化的“任务单元”&#xff08;Task Unit, TU&#xff09;进行计量。每个…...

3个理由选择Clipy:重新定义你的macOS剪贴板体验

3个理由选择Clipy&#xff1a;重新定义你的macOS剪贴板体验 【免费下载链接】Clipy Clipboard extension app for macOS. 项目地址: https://gitcode.com/gh_mirrors/cl/Clipy Clipy是一款专为macOS用户设计的剪贴板增强应用&#xff0c;它不仅能记录你的剪贴板历史&…...

VCNL系列接近传感器特性与工程应用解析

1. VCNL系列接近传感器核心特性解析VCNL4010、VCNL4020和VCNL3020这三款接近传感器代表了当前集成式光学传感方案的最高水平。我在工业自动化项目中多次采用该系列传感器&#xff0c;其最显著的特点是"三合一"封装设计——将红外发射器、PIN光电二极管和信号处理IC集…...

如何用XiaoMusic让小爱音箱变身你的私人音乐管家:5个超实用场景解析

如何用XiaoMusic让小爱音箱变身你的私人音乐管家&#xff1a;5个超实用场景解析 【免费下载链接】xiaomusic 使用小爱音箱播放音乐&#xff0c;音乐使用 yt-dlp 下载。 项目地址: https://gitcode.com/GitHub_Trending/xia/xiaomusic 还在为小爱音箱只能播放特定平台的音…...

weave-compose实战:用Docker Compose语法轻松构建多主机容器集群

1. 项目概述与核心价值最近在折腾容器编排&#xff0c;特别是想找一个比Kubernetes更轻量、更贴近Docker原生体验的方案。在GitHub上闲逛时&#xff0c;发现了Adityaraj0421/weave-compose这个项目。乍一看名字&#xff0c;以为是Docker Compose的某个魔改版&#xff0c;但深入…...

深入Android系统源码:screencap命令背后,SurfaceFlinger如何“画”出一张图?

深入Android系统源码&#xff1a;screencap命令背后&#xff0c;SurfaceFlinger如何“画”出一张图&#xff1f; 当我们轻敲adb shell screencap -p /sdcard/screenshot.png命令时&#xff0c;手机屏幕上瞬间闪现的内容便被永久定格。这个看似简单的操作背后&#xff0c;却隐藏…...

VidToText

链接&#xff1a;https://pan.quark.cn/s/370e0f7f3f42vidToText 离线语音转文字 工具&#xff0c;绝对能帮你解放双手&#xff0c;自带模型不用联网&#xff0c;95% 高准确率&#xff0c;音视频秒转文字&#xff0c;办公和创作效率直接翻倍&#xff01;且这款软件免费使用&…...

tokenviz:量化你的AI编程助手使用习惯,生成GitHub风格热力图

1. 项目概述&#xff1a;你的AI编码助手使用报告作为一名每天和代码打交道的开发者&#xff0c;我发现自己越来越依赖AI编程助手了。从最初的Copilot补全&#xff0c;到后来深度使用Cursor、Claude Code&#xff0c;这些工具已经成了我工作流中不可或缺的一部分。但用久了&…...

点云匹配方法 NDT(正态分布变换)

1. 正态分布变换 (NDT) 在点云匹配中&#xff0c;ICP基于距离直接最优化变换矩阵的参数&#xff0c;由于是欠定方程且旋转矩阵的约束&#xff0c;使得结果很难优化&#xff0c;为此在新的维度优化变换矩阵的参数&#xff0c;被很好的提出&#xff1a; 先将参考点云&#xff0…...

零代码部署 OpenClaw:Win11 一键安装与使用教程

OpenClaw&#xff08;小龙虾&#xff09;Windows 11 一键部署教程 2026 最新版 零代码免配置解压即用适用系统&#xff1a;Windows 11 专业版 / 家庭版 / 正式版&#xff08;全版本兼容&#xff09; 项目介绍&#xff1a;OpenClaw 是 GitHub 星标 28W 的开源本地 AI 智能体&am…...