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

在Qt窗口中添加右键菜单

在Qt窗口中添加右键菜单

  • 基于鼠标的事件实现
    • 流程
    • demo
  • 基于窗口的菜单策略实现
    • Qt::DefaultContextMenu
    • Qt::ActionsContextMenu
    • Qt::CustomContextMenu
      • 信号API

基于鼠标的事件实现

流程

需要使用:事件处理器函数(回调函数)

  1. 在当前窗口类中重写鼠标操作相关的的事件处理器函数,有两个可以选择
// 以下两个事件二选一即可, 只是事件函数被调用的时机不同罢了
// 这个时机对右键菜单的显示没有任何影响
[virtual protected] void QWidget::mousePressEvent(QMouseEvent *event);
[virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event);
  1. 在数据表事件处理器函数内部判断是否按下了鼠标右键
  2. 如果按下了鼠标右键创建菜单对象(也可以提前先创建处理), 并将其显示出来
// 关于QMenu类型的菜单显示需要调用的 API
// 参数 p 就是右键菜单需要显示的位置, 这个坐标需要使用屏幕坐标
// 该位置坐标一般通过调用 QCursor::pos() 直接就可以得到了
QAction *QMenu::exec(const QPoint &p, QAction *action = nullptr);

demo

在头文件中,添加 mousePressEvent 函数的声明

在这里插入图片描述

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private:Ui::MainWindow *ui;protected:// 鼠标按下, 该函数被Qt框架调用, 需要重写该函数void mousePressEvent(QMouseEvent *event);
};
#endif // MAINWINDOW_H

在对应的cpp中,添加 mousePressEvent 函数的定义

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QIcon"
#include "QTextEdit"
#include "QMessageBox"
#include "QMouseEvent"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);// 创建图标对象QIcon Q(":/new/prefix1/img/a.png");// QWidget类的 公共成员函数this->setWindowIcon(Q);// 给窗口设置图标// 弊端: 发布的 exe 必须要加载 d:\\pic\\1.ico 如果当前主机对应的目录中没有图片, 图标就无法被加载// 发布 exe 需要额外发布图片, 将其部署到某个目录中//setWindowIcon(QIcon("d:\\pic\\1.ico"));//使用API布局// 创建符窗口对象//QWidget *window1 = new QWidget();// 创建若干个子窗口对象QPushButton *button1 = new QPushButton("One");QPushButton *button2 = new QPushButton("Two");QPushButton *button3 = new QPushButton("Three");QPushButton *button4 = new QPushButton("Four");QPushButton *button5 = new QPushButton("Five");// 创建水平布局对象QHBoxLayout *layout1 = new QHBoxLayout;// 将子窗口添加到布局中layout1->addWidget(button1);layout1->addWidget(button2);layout1->addWidget(button3);layout1->addWidget(button4);layout1->addWidget(button5);// 将水平布局设置给父窗口对象this->ui->widget_3->setLayout(layout1);// 显示父窗口this->ui->widget_3->show();//使用API布局//创建垂直布局// 创建符窗口对象//QWidget *window2 = new QWidget;// 创建若干个子窗口对象QPushButton *button21 = new QPushButton("One");QPushButton *button22 = new QPushButton("Two");QPushButton *button23 = new QPushButton("Three");QPushButton *button24 = new QPushButton("Four");QPushButton *button25 = new QPushButton("Five");// 创建垂直布局对象QVBoxLayout *layout2 = new QVBoxLayout;// 将子窗口添加到布局中layout2->addWidget(button21);layout2->addWidget(button22);layout2->addWidget(button23);layout2->addWidget(button24);layout2->addWidget(button25);// 将水平布局设置给父窗口对象this->ui->widget_4->setLayout(layout2);// 显示父窗口this->ui->widget_4->show();//使用API布局//创建网格布局// 创建父窗口对象//QWidget* window3 = new QWidget;// 创建子窗口对象QPushButton *button31 = new QPushButton("One");QPushButton *button32 = new QPushButton("Two");QPushButton *button33 = new QPushButton("Three");QPushButton *button34 = new QPushButton("Four");QPushButton *button35 = new QPushButton("Five");QPushButton *button6 = new QPushButton("Six");// 多行文本编辑框QTextEdit* txedit3 = new QTextEdit;txedit3->setText("我占用了两行两列的空间哦。");QGridLayout* layout = new QGridLayout;// 按钮起始位置: 第1行, 第1列, 该按钮占用空间情况为1行1列layout->addWidget(button1, 0, 0);// 按钮起始位置: 第1行, 第2列, 该按钮占用空间情况为1行1列layout->addWidget(button2, 0, 1);// 按钮起始位置: 第1行, 第3列, 该按钮占用空间情况为1行1列layout->addWidget(button3, 0, 2);// 编辑框起始位置: 第2行, 第1列, 该按钮占用空间情况为2行2列layout->addWidget(txedit3, 1, 0, 2, 2);// 按钮起始位置: 第2行, 第3列, 该按钮占用空间情况为1行1列layout->addWidget(button4, 1, 2);// 按钮起始位置: 第3行, 第3列, 该按钮占用空间情况为1行1列layout->addWidget(button5, 2, 2);// 按钮起始位置: 第4行, 第1列, 该按钮占用空间情况为1行3列layout->addWidget(button6, 3, 0, 1, 3);// 网格布局设置给父窗口对象this->ui->widget_5->setLayout(layout);// 显示父窗口this->ui->widget_5->show();
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::mousePressEvent(QMouseEvent *event){// 判断用户按下的是哪一个鼠标键if(event->button() == Qt::RightButton){// 弹出一个菜单, 菜单项是 QAction 类型QMenu menu;QAction* act = menu.addAction("C++");connect(act, &QAction::triggered, this, [=](){QMessageBox::information(this, "title", "您选择的是C++...");});menu.addAction("Java");menu.addAction("Python");menu.exec(QCursor::pos()); // 右键菜单被模态显示出来了}}

效果

在这里插入图片描述
在这里插入图片描述

我稍作修改,添加左击和右击的效果:

void MainWindow::mousePressEvent(QMouseEvent *event){// 判断用户按下的是哪一个鼠标键if(event->button() == Qt::RightButton){// 弹出一个菜单, 菜单项是 QAction 类型QMenu menu;QAction* act1 = menu.addAction("C++");connect(act1, &QAction::triggered, this, [=](){QMessageBox::information(this, "title", "您选择的是C++...");});QAction* act2 =menu.addAction("Java");connect(act2, &QAction::triggered, this, [=](){QMessageBox::information(this, "title", "您选择的是JAVA...");});QAction* act3 =menu.addAction("Python");connect(act3, &QAction::triggered, this, [=](){QMessageBox::information(this, "title", "您选择的是PYthon...");});menu.exec(QCursor::pos()); // 右键菜单被模态显示出来了}if(event->button() == Qt::LeftButton){// 弹出一个菜单, 菜单项是 QAction 类型QMenu menu;QAction* act = menu.addAction("hello");connect(act, &QAction::triggered, this, [=](){QMessageBox::information(this, "title", "您使用鼠标左键点击了一下");});menu.exec(QCursor::pos()); // 右键菜单被模态显示出来了}}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

基于窗口的菜单策略实现

这种方式是使用 Qt 中 QWidget类中的右键菜单函数 QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy) 来实现

API如下:

// 函数原型:
void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy);
参数: 	- Qt::NoContextMenu	     --> 不能实现右键菜单- Qt::PreventContextMenu   --> 不能实现右键菜单- Qt::DefaultContextMenu   --> 基于事件处理器函数 QWidget::contextMenuEvent() 实现- Qt::ActionsContextMenu   --> 添加到当前窗口中所有 QAction 都会作为右键菜单项显示出来- Qt::CustomContextMenu    --> 基于 QWidget::customContextMenuRequested() 信号实现

Qt::DefaultContextMenu

第一步:在相应的窗口的类的头文件中添加这个函数 QWidget::contextMenuEvent() 的声明
在这里插入图片描述

第二步在这个窗口类的构造函数设置右键菜单策略

在这里插入图片描述

第三步在这个窗口类的源文件中重写事件处理器函数 contextMenuEvent()
在这里插入图片描述

Qt::ActionsContextMenu

使用这个策略实现右键菜单, 是最简单的一种, 我们只需要创建一些 QAction类型的对象并且将他们添加到当前的窗口中, 当我们在窗口中点击鼠标右键这些QAction类型的菜单项就可以显示出来了。

Qmainwindow的调用代码:
在这里插入图片描述
在mydialog2中:
在这里插入图片描述

#include "mydialog2.h"
#include "ui_mydialog2.h"
#include "QAction"
#include "QMessageBox"myDialog2::myDialog2(QWidget *parent) :QDialog(parent),ui(new Ui::myDialog2)
{ui->setupUi(this);// 只要将某个QAction添加给对应的窗口, 这个action就是这个窗口右键菜单中的一个菜单项了// 在窗口中点击鼠标右键, 就可以显示这个菜单setContextMenuPolicy(Qt::ActionsContextMenu);// 给当前窗口添加QAction对象QAction* act1  = new QAction("C++");QAction* act2 = new QAction("Java");QAction* act3  = new QAction("Python");this->addAction(act1);this->addAction(act2);this->addAction(act3);connect(act1, &QAction::triggered, this, [=](){QMessageBox::information(this, "title", "您选择的是C++...");});}myDialog2::~myDialog2()
{delete ui;
}

Qt::CustomContextMenu

使用这个策略实现右键菜单, 当点击鼠标右键,窗口会产生一个 QWidget::customContextMenuRequested() 信号,注意仅仅只是发射信号,意味着要自己写显示右键菜单的槽函数(slot),这个信号是QWidget唯一与右键菜单有关的信号。

信号API

// 注意: 信号中的参数pos为当前窗口的坐标,并非屏幕坐标,右键菜单显示需要使用屏幕坐标
[signal] void QWidget::customContextMenuRequested(const QPoint &pos)

在这里插入图片描述

#include "mydialog3.h"
#include "ui_mydialog3.h"
#include "QMenu"
#include "QMessageBox"myDialog3::myDialog3(QWidget *parent) :QDialog(parent),ui(new Ui::myDialog3)
{ui->setupUi(this);// 策略 Qt::CustomContextMenu// 当在窗口中点击鼠标右键, 窗口会发出一个信号: QWidget::customContextMenuRequested()// 对应发射出的这个信号, 需要添加一个槽函数, 用来显示右键菜单this->setContextMenuPolicy(Qt::CustomContextMenu);connect(this, &QDialog::customContextMenuRequested, this, [=](const QPoint &pos){// 参数 pos 是鼠标按下的位置, 但是不能直接使用, 这个坐标不是屏幕坐标, 是当前窗口的坐标// 如果要使用这个坐标需要将其转换为屏幕坐标QMenu menu;QAction* act = menu.addAction("C++");connect(act, &QAction::triggered, this, [=](){QMessageBox::information(this, "title", "您选择的是C++...");});QAction* act2 = menu.addAction("Java");connect(act2, &QAction::triggered, this, [=](){QMessageBox::information(this, "title", "您选择的是加瓦");});menu.addAction("Python");// menu.exec(QCursor::pos());// 将窗口坐标转换为屏幕坐标QPoint newpt = this->mapToGlobal(pos);menu.exec(newpt);});}myDialog3::~myDialog3()
{delete ui;
}

相关文章:

在Qt窗口中添加右键菜单

在Qt窗口中添加右键菜单 基于鼠标的事件实现流程demo 基于窗口的菜单策略实现Qt::DefaultContextMenuQt::ActionsContextMenuQt::CustomContextMenu信号API 基于鼠标的事件实现 流程 需要使用:事件处理器函数(回调函数) 在当前窗口类中重写鼠标操作相关的的事件处理器函数&a…...

Day8 智慧商城

项目演示 项目收获 创建项目 调整初始化目录 1.删components里的所有文件 2.删views里的所有文件 3.router/index.js 删路由 删规则 import Vue from vue import VueRouter from vue-routerVue.use(VueRouter)const router new VueRouter({routes: [] })export default route…...

LeetCode:Hot100python版本之回溯

回溯算法其实是纯暴力搜索。for循环嵌套是写不出的 组合&#xff1a;没有顺序 排列&#xff1a;有顺序 回溯法可以抽象为树形结构。只有在回溯算法中递归才会有返回值。 46. 全排列 排列是有顺序的。 组合类问题用startindex&#xff0c;排序类问题用used&#xff0c;来标…...

分布式事务理论基础

今天啊&#xff0c;本片博客我们一起来学习一下微服务中的一个重点和难点知识&#xff1a;分布式事务。 我们会基于Seata 这个框架来学习。 1、分布式事务问题 事务&#xff0c;我们应该比较了解&#xff0c;我们知道所有的事务&#xff0c;都必须要满足ACID的原则。也就是 …...

线性代数强化第三章

目录 一&#xff0c;关于A伴随&#xff0c;A逆与初等矩阵 二&#xff0c;分块矩阵 三&#xff0c;矩阵方程 ​ 一&#xff0c;关于A伴随&#xff0c;A逆与初等矩阵 如何证明行列式的值不能是0&#xff1b; 此秩为1. 法一&#xff1a; 法二&#xff1a; 不用看是列变换还是行变…...

搭建自己的私有 开源LoRaWAN 网络服务器(The ThingsStack)---之配置

介绍 这是使用 Docker 在您自己的硬件上安装 Things Stack Enterprise 或开源代码以运行您自己的私有 LoRaWAN 网络服务器的指南。 运行 The Things Stack 的方法有多种。 Things Stack 开源和企业发行版旨在在您自己的硬件上运行,本指南也对此进行了介绍。 对于具有高吞吐量的…...

多维时序 | MATLAB实现SCNGO-CNN-Attention多变量时间序列预测

多维时序 | MATLAB实现SCNGO-CNN-Attention多变量时间序列预测 目录 多维时序 | MATLAB实现SCNGO-CNN-Attention多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.SCNGO-CNN-Attention超前24步多变量回归预测算法。 程序平台&#xff1a;无Attention适…...

clickhouse的删除和更新

clickhouse不擅长更新和删除操作&#xff0c;更新操作很重&#xff0c;更新是重新创建一个分区&#xff0c;更新完后&#xff0c;太混之前的 ClickHouse提供了DELETE和UPDATE的能力&#xff0c;这类操作被称为Mutation查询&#xff0c;它可以看作ALTER语句的变种。虽然Mutation…...

微前端 - qiankun

qiankun 是一个基于 single-spa 的微前端实现库&#xff0c;旨在帮助大家能更简单、无痛的构建一个生产可用微前端架构系统。 本文主要记录下如何接入 qiankun 微前端。主应用使用 vue2&#xff0c;子应用使用 vue3、react。 一、主应用 主应用不限技术栈&#xff0c;只需要提…...

前端编辑页面修改后和原始数据比较差异

在软件研发过程中&#xff0c;会遇到很多编辑页面&#xff0c;有时编辑页面和新增页面长的基本上一样&#xff0c;甚至就是一套页面供新增和编辑共用。编辑页面的场景比较多&#xff0c;例如&#xff1a; 场景一、字段比较多&#xff0c;但实际只修改了几个字段&#xff0c;如…...

docker第一次作业

docker第一次作业 1.安装docker服务&#xff0c;配置镜像加速器 yum install -y yum-utils device-mapper-persistent-data lvm2 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo sed -i sdownload.docker.commirrors.aliy…...

Springboot3.0.0+集成SpringDoc并配置knife4j的UI

环境&#xff1a;JDK17,Springboot3,springdoc2,knife4j 4 Springdoc本身也是集成了Swagger3&#xff0c;而knife4j美化了Swagger3的UI Knife4j官网&#xff1a; 快速开始 | Knife4j Springdoc官网 OpenAPI 3 Library for spring-boot 1.pom配置 由于此knife4j内依赖了S…...

电脑运行缓慢?4个方法,加速电脑运行!

“我电脑才用了没多久哎&#xff01;怎么突然就变得运行很缓慢了呢&#xff1f;有什么方法可以加速电脑运行速度吗&#xff1f;真的很需要&#xff0c;看看我吧&#xff01;” 电脑的运行速度快会让用户在使用电脑时感觉愉悦&#xff0c;而电脑运行缓慢可能会影响我们的工作效率…...

3.Docker 搭建 MySQL8.0

1、docker仓库搜索mysql docker search mysql2、docker仓库拉取mysql8.0 docker pull mysql:8.0 备注&#xff1a; docker pull mysql //默认拉取最新版本3、查看本地仓库镜像是否下载成功 docker images mysql:8.04、安装运行mysql8.0容器 docker run -p 3306:3306 --name…...

Mybatis的SqlSource SqlNode BoundSql

学习链接 MyBatis SqlSource解析 【Mybatis】Mybatis源码之SqlSource#getBoundSql获取预编译SQL Mybatis中SqlSource解析流程详解 Mybatis TypeHandler解析 图解 Mybatis的SqlSource&SqlNode - processon DynamicSqlSource public class DynamicSqlSource implement…...

html动态爱心代码【二】(附源码)

目录 前言 效果演示 内容修改 完整代码 总结 前言 七夕马上就要到了&#xff0c;为了帮助大家高效表白&#xff0c;下面再给大家带来了实用的HTML浪漫表白代码(附源码)背景音乐&#xff0c;可用于520&#xff0c;情人节&#xff0c;生日&#xff0c;表白等场景&#xff0c…...

【Rust】Rust学习 第十六章无畏并发

安全且高效的处理并发编程是 Rust 的另一个主要目标。并发编程&#xff08;Concurrent programming&#xff09;&#xff0c;代表程序的不同部分相互独立的执行&#xff0c;而 并行编程&#xff08;parallel programming&#xff09;代表程序不同部分于同时执行&#xff0c;这两…...

系统报错mfc100u.dll丢失的解决方法(完美解决dll问题)

系统文件mfc100u.dll丢失和出错&#xff0c;极有可能是盗号木马、流氓软件等恶意程序所导致&#xff0c;其感染相关文件并加载起来&#xff0c;一旦杀毒软件删除被感染的文件&#xff0c;就会导致相关组件缺失&#xff0c;游戏等常用软件运行不起来&#xff0c;且提示“无法启动…...

docker compose的用法

目录 一、Docker-Compose介绍 1.1 Docker-Compose的概述 1.2 Docker-Compose 用来实现Docker容器快速编排 1.3 Docker-compose模板文件简介 二、YAML简介 2.1 YAML的概述 2.2 YAML的基本语法规则 2.3 YAML支持的数据架构 三、配置内部常用字段 四、Docker-compose 常…...

Linux: 使用 ssh 连接其他服务器

通过ifconfig 查看要连接的服务器地址&#xff1a; ubuntuubuntu1804-0172:/media/sangfor/vdc$ ssh ubuntu192.168.11.49 输入要连接的服务器密码: ubuntua192.168.1149 s password: 连接服务器成功&#xff1a;...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...

spring Security对RBAC及其ABAC的支持使用

RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型&#xff0c;它将权限分配给角色&#xff0c;再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...

es6+和css3新增的特性有哪些

一&#xff1a;ECMAScript 新特性&#xff08;ES6&#xff09; ES6 (2015) - 革命性更新 1&#xff0c;记住的方法&#xff0c;从一个方法里面用到了哪些技术 1&#xff0c;let /const块级作用域声明2&#xff0c;**默认参数**&#xff1a;函数参数可以设置默认值。3&#x…...

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…...

DeepSeek越强,Kimi越慌?

被DeepSeek吊打的Kimi&#xff0c;还有多少人在用&#xff1f; 去年&#xff0c;月之暗面创始人杨植麟别提有多风光了。90后清华学霸&#xff0c;国产大模型六小虎之一&#xff0c;手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水&#xff0c;单月光是投流就花费2个亿。 疯…...