在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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/52507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式之中介者模式(Mediator)的C++实现

1、中介者模式的提出 在软件组件开发过程中&#xff0c;如果存在多个对象&#xff0c;且这些对象之间存在的相互交互的情况不是一一对应的情况&#xff0c;这种功能组件间的对象引用关系比较复杂&#xff0c;耦合度较高。如果有一些新的需求变化&#xff0c;则不易扩展。中介者…

Vue教程(五):样式绑定——class和style

1、样式代码准备 样式提前准备 <style>.basic{width: 400px;height: 100px;border: 1px solid black;}.happy{border: 4px solid red;background-color: rgba(255, 255, 0, 0.644);background: linear-gradient(30deg, yellow, pink, orange, yellow);}.sad{border: 4px …

腾讯云下一代CDN -- EdgeOne加速MinIO对象存储

省流 使用MinIO作为EdgeOne的源站。 背景介绍 项目中需要一个兼容S3协议的对象存储服务&#xff0c;腾讯云的COS虽然也兼容S3协议&#xff0c;但是也只是支持简单的上传下载&#xff0c;对于上传的时候同时打标签这种需求&#xff0c;就不兼容S3了。所以决定自建一个对象存储…

学习JAVA打卡第四十天

对象的字符串表示 在此类中我们讲过&#xff0c;所有的类都默认是java.lang包中object类的子类或间接子类。 Object类有一个public String toString&#xff08;&#xff09;方法,一个对象通过调用该方法可以获得该对象的字符串表示。一个对象调用toString法&#xff08;&…

AURIX TriCore内核架构学习笔记

名词缩写 ISA - Instruction Set Architecture&#xff0c;指令集架构PC - Program Counter, holds the address of the instruction that is currently runningGPRs - 32 General Purpose RegistersPSW - Program Status WordPCXI - Previous Context InformationCSA - Conte…

【Python编程】将同一种图片分类到同一文件夹下,并且将其分类的路径信息写成txt文件进行保存

注&#xff1a;数据结构同上一篇博文类似 一、代码 import os import cv2 import shutilpath0os.getcwd()\\apple\\RGB path1os.getcwd()\\apple\\tof_confidence # path2os.getcwd()\\apple\\tof_depth # path3os.getcwd()\\apple\\tof_depthRGB # path4os.getcwd()\\apple\…

HTML番外篇(五)-移动端适配

一、媒体查询 1.认识媒体查询 媒体查询是一种提供给开发者针对不同设备需求进行定制化开发的一个接口。 你可以根据设备的类型&#xff08;比如屏幕设备、打印机设备&#xff09;或者特定的特性(比如屏幕的宽度)来修改你的页面。 媒体查询的使用方式主要有三种&#xff1a;…

Linux socket网络编程概述 和 相关API讲解

socket网络编程的步骤 大体上&#xff0c;连接的建立过程就是&#xff1a;服务器在确定协议类型后&#xff0c;向外广播IP地址和端口号&#xff0c;并监听等待&#xff0c;直到客户端获取了IP地址和端口号并成功连接&#xff1a; 使用socket来进行tcp协议的网络编程的大体步骤…

Qt快速学习(二)--QMainWindow,对话框,布局管理器,常用控件

目录 1 QMainWindow 1.1 菜单栏 1.2 工具栏 1.3 状态栏 1.4 铆接部件 1.5 核心部件&#xff08;中心部件&#xff09; 1.6 资源文件 2 对话框QDialog 2.1 基本概念 2.2 标准对话框 2.3 自定义消息框 2.4 消息对话框 2.5 标准文件对话框 3 布局管理器 3.1 系统…

axios / fetch 实现 stream 流式请求

axios 是一个支持node端和浏览器端的易用、简洁且高效的http库。本文主要介绍 axios 如何实现 stream 流式请求&#xff0c;注意这里需要区分 node 环境和浏览器环境。 一、node端 代码演示&#xff1a; const axios require(axios);axios({method: get,url: http://tiven.c…

Spring Boot 整合MyBatis-Plus

&#x1f600;前言 本篇博文是关于Spring Boot 整合MyBatis-Plus的&#xff0c;希望你能够喜欢&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的…

储能运行约束的Matlab建模方法

最近一段时间有很多人问我最优潮流计算中储能系统的建模方法。部分朋友的问题我回复了&#xff0c;有些没有回消息的&#xff0c;我就不再一一回复了&#xff0c;在这里我写一篇博客统一介绍一下。 1.储能系统介绍 首先&#xff0c;让【GPT】简单介绍一下储能系统&#xff1a;…

Maven解析

目录 Maven的概念 Pom 项目坐标 仓库 Maven环境搭建 安装jdk 配置maven 配置本地仓库地址 配置阿里云 maven 镜像仓库&#xff0c;下载速度更快 在idea中配置maven ​编辑 pom中名词解释 Maven命令 Maven的概念 Maven 是 Apache 软件基金会的一个开源项目,是一个…

PhantomJS+java 后端生成echart图表的图片

PhantomJSjava 后端生成echart图表的图片 前言源码效果实现echarts-convertPhantomJS实现echarts截图得到图片java延时读取base64数据 参考 前言 该项目仅用作个人学习使用 源码 地址 docker镜像&#xff1a; registry.cn-chengdu.aliyuncs.com/qinjie/java-phantomjs:1.0 …

航空电子设备中的TSN通讯架构—直升机

前言 以太网正在迅速取代传统网络&#xff0c;成为航空电子设备和任务系统的核心高速网络。本文提出了以太网时间敏感网络(TSN)在航空电子设备上应用的技术优势问题。在实际应用中&#xff0c;TSN已成为一个具有丰富的机制和协议的工具箱&#xff0c;可满足与时间和可靠性相关…

vue2 computed计算属性,watch侦听器

一、今日学习目标 1.指令补充 指令修饰符v-bind对样式增强的操作v-model应用于其他表单元素 2.computed计算属性 基础语法计算属性vs方法计算属性的完整写法成绩案例 3.watch侦听器 基础写法完整写法 二、指令修饰符 1.什么是指令修饰符&#xff1f; 所谓指令修饰符就是…

windows下cmd快速生成大文件命令

fsutil file createnew [文件名] [文件大小]

卷轴模式解析:如何实现用户留存、引流拓客

随着现代技术的不断发展和数字货币市场的日益成熟&#xff0c;越来越多的数字货币项目被推向市场。而消费者需求日益复杂&#xff0c;单一的玩法模式已经不能满足消费者追求更好购物体验的需求。电商平台需要尊重消费者的意愿&#xff0c;满足消费者的多样化需求&#xff0c;这…

天眼查接口 查询企业信息API 企查查接口

item_get-获得tyc详情 tyc.item_get 公共参数 请求地址: https://api-gw.cn/tyc/item_get 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff0…

BLFS学习系列 第26章. 显示管理器 —— 总述

显示管理器&#xff08;Display Manager&#xff09;是用于启动图形显示&#xff08;当前为X服务器&#xff09;并为窗口管理器或桌面环境提供登录功能的图形程序。 有许多显示管理器可用。一些较为知名的包括&#xff1a;GDM、KDM&#xff08;已弃用&#xff09;、LightDM、L…