Qt之快捷键、事件处理、自定义按键——完成记事本项目

快捷键

我们电脑中的记事本中还支持快捷键,如

“CTRL+O”打开文件、“CTRL+S”保存文件

在Qt中使用QShortcut这个类创建快捷键

在.cpp文件的构造函数中创建QShortcut对象,绑定打开文件和保存文件的槽函数

放大缩小字体

还是在.cpp的构造函数中编写代码

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setLayout(ui->verticalLayout);ui->widget_2->setLayout(ui->horizontalLayout_2);connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(oncurrentIndex(int)));connect(ui->textEdit,SIGNAL(cursorPositionChanged()),this,SLOT(oncursorPosition()));QShortcut *shortcutOpen=new QShortcut(QKeySequence(tr("Ctrl+O","File|Open")),this);        //添加快捷键QShortcut *shortcutSave=new QShortcut(QKeySequence(tr("Ctrl+S","File|Save")),this);connect(shortcutOpen,&QShortcut::activated,[=](){on_Bopen_clicked();});                    //绑定信号与槽(指针)connect(shortcutSave,&QShortcut::activated,[=](){on_Bsave_clicked();});QShortcut *shortcutZoomBig=new QShortcut(QKeySequence(tr("Ctrl+Shift+=","File|Save")),this);   //ctrl、shift、+号同时按下(+与=在同一个位置)QShortcut *shortcutZoomSmall=new QShortcut(QKeySequence(tr("Ctrl+Shift+-","File|Save")),this); connect(shortcutZoomBig,&QShortcut::activated,[=](){QFont font = ui->textEdit->font();            //获取当前字体信息int fontSize = font.pointSize();              //获取当前字体大小if(fontSize==-1) return;int newfontSize=fontSize+1;                   //改变字体大小font.setPointSize(newfontSize);               //设置新字体大小ui->textEdit->setFont(font);});  connect(shortcutZoomSmall,&QShortcut::activated,[=](){QFont font = ui->textEdit->font();            //获取当前字体信息int fontSize = font.pointSize();              //获取当前字体大小if(fontSize==-1) return;int newfontSize=fontSize-1;                   //改变字体大小font.setPointSize(newfontSize);               //设置新字体大小ui->textEdit->setFont(font);});   
}

事件处理

事件是 Qt 程序与用户(或操作系统)交互的基本单元:用户按下鼠标、键盘输入、窗口被遮挡或暴露、定时器到期……都会产生一个 QEvent 对象。

过去我们常用“信号-槽”机制来处理用户动作,但信号-槽只能覆盖 Qt 已定义好的“高层语义”,遇到“关闭窗口时询问是否保存”“拖拽窗口时限制范围”这类底层或组合行为,就必须介入真正的事件处理流程。

在 Qt 中,事件处理分为四个连贯的步骤:

  1. 事件派发(dispatch):QApplication::notify() 把事件发给目标对象;

  2. 事件过滤(filter):沿途的所有 QObject::eventFilter() 都有机会截断或修改事件;

  3. 事件分发(delivery):目标对象内部的 QWidget::event() 根据事件类型再细分;

  4. 事件处理(handle):具体虚函数如 mousePressEvent()closeEvent() 最终被执行。

在Qwidget中的保护成员中,还有如下这些事件处理函数,如closeEvent()可以关闭窗口,我们重写事件处理函数也可以在一定程度上处理事件。

事件重写

我们再来添加一个关闭窗口时的弹窗询问

打开.h文件,声明重写closeEvent()事件处理函数(widget继承于Qwidget)

同时按下“ALT+ENTER”,在.cpp文件中添加实现

void Widget::closeEvent(QCloseEvent *event)           //记得添加头文件
{int ret=QMessageBox::warning(this,tr("My Application"),tr("close the window.\n""Do you want to close the window?"),QMessageBox::Yes|QMessageBox::No);      //弹窗switch (ret) {case QMessageBox::Yes:event->accept();        //QCloseEvent继承于QEvent,accept接受事件,ignore忽略 break;case QMessageBox::No:event->ignore();break;}}

自定义按键

按键个性化设置

新建一个项目(同前),然后自定义一个按钮

右键项目,点击“Add New”

点击“C++ Class”,点击“choose”

继承于QWidget,点击“下一步”,点击“完成”

需要在.h文件中声明的成员如下

再次右键项目名称,点击“Add New”,添加一个Qt的资源文件

点击“Add Files”,选择3张图片样式添加(在项目文件下添加),“CTRL+S”保存

在.cpp文件中实现重写逻辑

右键复制图片文件地址

#include "mybutton.h"#include <QPainter>MyButton::MyButton(QWidget *parent) : QWidget(parent)
{pic.load(":/p1.png");   //加载图片(初始图片)setFixedSize(pic.size());  //设置按键大小为图片大小update();                  //刷新,触发paintEvent()
}void MyButton::mousePressEvent(QMouseEvent *event)    
{pic.load(":/p3.png");update();
}void MyButton::leaveEvent(QEvent *event)
{pic.load(":/p1.png");update();    
}void MyButton::enterEvent(QEvent *event)
{pic.load(":/p2.png");update();    
}void MyButton::paintEvent(QPaintEvent *event)
{QPainter painter(this);                    //绘画师painter.drawPixmap(rect(),pic);            //绘制图像(矩形,位图)}

打开.ui文件,托入一个widget控件,右键,点击“提升为”

输入新按钮的类的名称,点击“添加”

点击运行文件,按钮图标能正常转换

这样自定义后按键的形状就能随自己设计,更好看一些(可以用图片等)

自定义按键的信号与槽

在"button.h"文件中声明点击信号

在widget.cpp中引入button的头文件

connect绑定信号与槽

并在button.cpp文件,在鼠标信号点击处,发送点击信号

点击“打开”按钮后,能正常发射信号

事件重写实现滚轮放大缩小字体

标准的QTextEdit控件并不支持“CTAL+鼠标滚轮”,所以我们要自定义一个MyTextEdit出来,再将notebook原来的textEdit提升为我们自定义的textEdit类(原代码.c文件不用修改,都是继承于QtextEdit实现)

右键项目名称,新建一个类文件

标注父控件

在我们的MyTextEdit构造时还需标注父控件,使MyTextEdit与ui中的TextEdit联系起来(ui中所有控件都有QWidget这个父亲)

“ALT+ENTER”添加构造函数的实现(把原来的删掉)

MyTextEdit::MyTextEdit(QWidget *parent):QTextEdit(parent)    //调用QtextEdit的构造函数实现
{}

再在.h文件中声明要实现的功能

#ifndef MYTEXTEDIT_H
#define MYTEXTEDIT_H#include <QTextEdit>class MyTextEdit : public QTextEdit
{
public:MyTextEdit(QWidget *parent);protected:void wheelEvent(QWheelEvent *e) override;              //鼠标滚轮事件void keyPressEvent(QKeyEvent *e) override;             //按键按下事件void keyReleaseEvent(QKeyEvent *e) override;           //按键松开事件
};#endif // MYTEXTEDIT_H

提升TextEdit

在ui中右键TextEdit,“提升为”

然后右边可以看到已经提升过来了

代码实现

放大和缩小字体的代码与之前快捷键实现重复了,所以直接把之前那段代码用函数封装调用就好了

widget.h添加声明

widget.cpp添加实现

使用事件函数基本的使用,我们已经能写出大致框架,但我们要实现的应该是“CTRL+滚轮”实现,但滚轮能够上下滑动

我们只要添加一个bool型的变量,使同时操作时再调用函数就可以了

以及除了同时按下,正常操作的反应要继承下来

#include "mytextedit.h"#include <QCloseEvent>MyTextEdit::MyTextEdit(QWidget *parent):QTextEdit(parent)    //调用QtextEdit的构造函数实现
{}void MyTextEdit::wheelEvent(QWheelEvent *e)
{if(ctrlKeyPressed==1){if(e->angleDelta().y()>0){                           //上滑缩小zoomIn();}else if(e->angleDelta().y()<0){zoomOut();}e->accept();                                         //处理完毕}else{QTextEdit::wheelEvent(e);                             //正常执行QTextEdit的滚轮事件}
}void MyTextEdit::keyPressEvent(QKeyEvent *e)
{if(e->key()==Qt::Key_Control){                          //Ctrl按下ctrlKeyPressed=1;}QTextEdit::keyPressEvent(e);                            //按键按下执行
}void MyTextEdit::keyReleaseEvent(QKeyEvent *e)
{if(e->key()==Qt::Key_Control){                          //Ctrl释放ctrlKeyPressed=0;}QTextEdit::keyReleaseEvent(e);
}

事件过滤器

对于Qt事件,我们主要把中重点放在事件处理和事件过滤

事件过滤器适用于:当你不想在修改子代码的情况下改变事件的行为(如上面的情况不添加新的类)。可在事件到达目标对象之前进行拦截和处理

先在.h文件添加声明

安装事件过滤器

在事件过滤器中,我们既要检测滚轮,又要检测“Ctrl”是否被按下。若单使用QEvent事件,检测滚轮会调用一次,检测ctrl按下又会调用一次。则两个事件不能同时被检测,所以我们换种方式检测滚轮。

bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(event->type()==QEvent::Wheel){             //事件是滚轮事件if(QGuiApplication::keyboardModifiers()==Qt::ControlModifier){    //ctrl被按下QWheelEvent *weelEvent=dynamic_cast<QWheelEvent*>(event);                   //转换类型if(weelEvent->angleDelta().y()>0){zoomIn();}else{zoomOut();}return true;                           //事件已执行}return false;                              //若ctrl没被按下,事件继续传递给目标对象}
}

至此,我们的记事本项目简单完成!

下图为up主老陈的总结

 

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

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

相关文章

Open cascade中如何使用BRepAlgoAPI_Splitter分割一个Face

理论介绍 在OpenCASCADE几何建模内核中&#xff0c;BRepAlgoAPI_Splitter是一个强大的工具&#xff0c;用于将一个形状&#xff08;Shape&#xff09;用另一个形状&#xff08;Tool&#xff09;进行分割。这种操作在CAD建模中非常常见&#xff0c;比如用平面切割实体、用曲线分…

【医疗 AI】Baichuan-M2 医疗大模型:技术解读与使用方法

【医疗 AI】Baichuan-M2 医疗大模型&#xff1a;技术解读与使用方法1. Baichuan-M2 医疗大模型简介1.1 基本信息1.2 下载地址1.3 技术特点2. Baichuan-M2 模型技术报告2.1 摘要2.2 医学性能评估2.2.1 HealthBench基准2.2.2 中国医疗场景对比评估2.3 系统架构2.3.1 验证器系统2.…

unity pcd 二进制版 简单显示文件对象(单色)

unity Point Cloud Viewer and Tool 那个插件不支持pcd二进制&#xff0c;而且网上到处都是AI 我恨这种AI滥用&#xff0c;提供不了一点价值 好了&#xff0c;言归正传 可以在Point Cloud Viewer and Tool这个插件报错地方转用这个代码&#xff0c;具体咋结合请自行研究。 …

强大的开源文档问答工具-Kotaemon

Kotaemon 是一个基于 RAG&#xff08;Retrieval-Augmented Generation&#xff09;架构的开源文档问答工具&#xff0c;为用户提供与文档对话的智能交互体验。该项目同时服务于终端用户和开发者&#xff0c;具有高度的可扩展性和定制化能力。技术栈分析核心技术栈后端框架Pytho…

区块链:搭建简单Fabric网络并调用智能合约

使用docker服务搭建Hyperledger/fabric网络的详细教程&#xff0c;实现构建多节点的简单联盟链&#xff0c;并编写、调用智能合约实现投票业务。 目录 背景知识 Hyperledger Fabric 基本组件 交易(Transaction) 智能合约 实验目的 实验环境 基础依赖 安装Golang 安装do…

Web前端面试题(2)

Web前端面试题(附答案及解析)&#xff08;2025.9月最新版&#xff09;-CSDN博客 1.link 与 import 的区别和用法 主要区别 特性<link>import语法类型HTML标签CSS规则加载方式并行加载&#xff08;与其他资源同时加载&#xff09;串行加载&#xff08;必须等待主CSS文件…

Paxos协议

目录 Paxos 是什么&#xff08;What&#xff09; Paxos 的目的&#xff08;Why&#xff09; 角色与职责&#xff08;Who&#xff09; 基本流程&#xff08;How&#xff09; 常见问题与对策 什么是多数派&#xff08;Quorum&#xff09; Paxos vs Raft 异同点 Paxos 是什…

第十二篇:Qcom Camx打印实时帧率 FPS

一、第一种方式(有些低平台可能没有) adb shell setprop persist.vendor.camera.enableFPSLog TRUE adb shell setprop persist.vendor.camera.systemLogEnable TRUE adb shell setprop vendor.debug.camera.overrideLogLevels 0xff chi-cdk/core/chiframework/chxextensi…

TRAE通用6A规则+敏捷开发5S规则

网上研究别人的一些规则,也搞一份给大家 6A工作流项目规则 身份定义 你是一位资深的软件架构师和工程师,具备丰富的项目经验和系统思维能力。你的核心优势在于: 上下文工程专家:构建完整的任务上下文,而非简单的提示响应 规范驱动思维:将模糊需求转化为精确、可执行的规…

【Nginx开荒攻略】Nginx主配置文件结构与核心模块详解:从0到1掌握nginx.conf:

目录 引言 1 nginx.conf的整体结构 2 main全局块详解 2.1 核心指令解析 2.1.1 user&#xff1a;运行用户 2.1.2 worker_processes&#xff1a;工作进程数 2.1.3 pid&#xff1a;PID文件路径 2.1.4 worker_rlimit_nofile&#xff1a;文件描述符限制 2.2 main块配置示例…

【前端教程】从基础到优化:一个登录页面的完善过程

最近做了一个简单的登录页面,主要练习了文本框的onfocus与onblur事件的使用。虽然功能实现了,但仔细想想还有不少可以改进的地方。今天就来分享一下这个登录页面的开发过程和优化思路。 初始实现与解析 先来看一下最初的实现代码: <!DOCTYPE html> <html> &l…

独家 | 抖音生活服务调整:涂晴接管市场和达人运营,旭凯担任北部大区负责人

文/刀客doc(头条精选作者)刀客doc独家获悉&#xff0c;9月8日抖音生活服务完成新一轮组织调整&#xff0c;并已在内部all hands完成官宣。此次调整主要涉及北部大区、达人运营与市场部三大条线的人事轮换与汇报关系变更。核心变动如下&#xff1a;涂晴&#xff0c;原抖音生活服…

class_9:java 抽象类和接口

抽象类 需要用abstract 修饰类和接口abstract class Person{String address;String name;abstract public void eat();abstract public void drink();public void printInfo(){System.out.println("name " name);}} class Student extends Person{public void eat()…

【C++】队列queue的使用

语法 在 C 中&#xff0c;队列的语法如下&#xff1a; #include <queue>// 声明队列 std::queue<Type> q;这里 Type 是队列中存储元素的数据类型。 常用操作 队列提供了以下常用操作&#xff1a; empty(): 检查队列是否为空。 size(): 返回队列中的元素数量。 fron…

HTTP 协议的基本格式

目录 &#xff08;一&#xff09;HTTP是什么 &#xff08;二&#xff09;报文格式 &#xff08;1&#xff09;请求 ①首行 1.URL 2.方法&#xff08;method&#xff09; Ⅰ.GET Ⅱ.POST Ⅲ.PUT Ⅳ.DELETE 3.版本号 ②请求头&#xff08;header&#xff09; 1.键值对…

计算机网络的基本概念-2

1、数据交换技术&#xff1a;电路交换、报文交换与分组交换网络核心部分的关键设备是路由器&#xff0c;其工作方式是分组交换。要理解分组交换&#xff0c;必须先了解其前两种技术。1. 电路交换 (Circuit Switching)核心思想&#xff1a;通信前必须预先建立一条专用的物理通路…

车载网络技术--SOME_IP协议详解

文章目录前言SOME/IP概念SOME/IP协议格式SOME/IP功能介绍序列化序列化规则发布和订阅服务发现&#xff08;SOME/IP-SD&#xff09;SOME/IP-TP协议使用场景SOME/IP-TP协议参考文章&#xff1a;前言 本文介绍了SOME/IP协议的具体内容&#xff0c;包括报文格式&#xff0c;协议选…

JVM 核心知识全解析:从类加载到垃圾回收的深度认知

什么是JVM&#xff1f; JVM全称&#xff08;Java Virtual Machine&#xff09;&#xff0c;中译为&#xff1a;Java虚拟机 本质&#xff1a;是一个运行在计算机上的程序 职责&#xff1a;运行Java字节码文件&#xff08;因为计算机只能认识机器码文件&#xff0c;所以需要JVM将…

Keepalived 负载均衡

Keepalived 负载均衡 Keepalived 可以与 LVS&#xff08;Linux Virtual Server&#xff09;结合&#xff0c;提供强大的四层负载均衡功能。它通过 IPVS&#xff08;IP Virtual Server&#xff09;内核模块实现高性能的负载分发。 核心组件 Virtual Server&#xff1a;虚拟服务器…

拷打DeepSeek实现自动生成差分电荷计算文件和后处理

差分电荷&#xff08;charge density difference&#xff09;是材料模拟中分析电子结构变化的直观工具。 它把成键后的真实电荷密度减去成键前各碎片叠加的电荷密度&#xff0c;得到一张“电子迁移地图” 于是可以一眼看出化学键形成时电子从哪里来到哪里去&#xff0c;表面吸…