Qt事件机制

文章目录

  • 1 事件机制
  • 2 ignore 和 accept
  • 3 bool event(QEvent *event);
  • 4 bool eventFilter(QObject *watched, QEvent *event);
  • 5 总结

1 事件机制

事件传递图:
在这里插入图片描述

记录一下事件的传递顺序,主要围绕 QEventFilter, QEvent, QKeyEvent等事件展开:
首先自定义一个继承于QLineEdit的类MyEdit

#include <QtWidgets/QWidget>
#include "ui_testwidgetradius.h"
#include "myedit.h"
#include <QKeyEvent>
class CTestWidgetRadius : public QWidget
{
	Q_OBJECT
public:
	CTestWidgetRadius(QWidget *parent = Q_NULLPTR);
protected:
	void keyPressEvent(QKeyEvent *event);
private:
	Ui::CTestWidgetRadiusClass ui;
	MyEdit* myEdit = nullptr;
};
#include "testwidgetradius.h"
#include <QStyleOption>
#include <QPainter>
#include <QDebug>
#include <QBitmap>
#include <QTextCodec>
#include <iostream>
#include <QToolTip>
bool CTestWidgetRadius::m_isHover = false;
QPoint CTestWidgetRadius::m_lastPoint = QPoint();
CTestWidgetRadius::CTestWidgetRadius(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
}

void CTestWidgetRadius::keyPressEvent(QKeyEvent *event)
{
	qDebug() << "parent keyPressEvent";
}
#include <QLineEdit>
#include <QKeyEvent>
#include <QEvent>
class MyEdit : public QLineEdit
{
	Q_OBJECT
protected:
	void keyPressEvent(QKeyEvent *);
public:
	MyEdit(QWidget *parent);
	~MyEdit();

};
#include <QDebug>
MyEdit::MyEdit(QWidget *parent)
	: QLineEdit(parent)
{
}

MyEdit::~MyEdit()
{
}

void MyEdit::keyPressEvent(QKeyEvent *event)
{
	 qDebug() << "myEdit keyPressEvent";
}

重写了keyPressEvent(QKeyEvent *event)这个函数之后,当我们在编辑框里面输入时,就会发现会触发这个键盘按下的事件,并且执行重写函数的代码,打印"myEdit keyPressEvent",但是此时并不能将你在键盘输入的字符显示在编辑框里面,这是因为你覆盖了QLineEdit的keyPressEvent(QKeyEvent *event)的内容,这个内容里面就包含了输入的一些处理,所以要想实现自己的代码,又想要实现父类的功能,就需要调用父类的函数,如下所示:

void MyEdit::keyPressEvent(QKeyEvent *event)
{
	 qDebug() << "myEdit keyPressEvent";
	 QLineEdit::keyPressEvent(event);//调用父类的函数 以实现空间原本的功能
}

这个时候就发现,可以顺利的键入字符了。此时你会发现只打印了"myEdit keyPressEvent",并没有打印"parent keyPressEvent",那么如何将这个事件传递呢?

2 ignore 和 accept

修改代码如下:

void MyEdit::keyPressEvent(QKeyEvent *event)
{
	 qDebug() << "myEdit keyPressEvent";
	 QLineEdit::keyPressEvent(event);//调用父类的函数 以实现控制原本的功能
	 event->ignore();//相当于 返回一个setAccepted(false) 传递事件给父类
}

此时就会打印myEdit keyPressEvent" 和 “parent keyPressEvent"了。这是因为调用ignore()只会这个事件就会被忽略,那这个事件就会继续传递,传递到他的父类去,也就是这里的Widget,就会执行父类的keyPressEvent(QKeyEvent *event)从而打印出"parent keyPressEvent”。
这里的 event->ignore();和setAccepted(false);作用是一样的。同理如果调用setAccepted(true);表示控件接收了这个事件,那么这个事件就不会继续传递了,和接受事件相对应的函数是event->accept();。

3 bool event(QEvent *event);

这个函数的级别是很高的,所有的具体的事件例如 void mousePressEvent(QMouseEvent *);
void keyPressEvent(QKeyEvent *);等事件,都会先由bool event(QEvent *event);函数来处理。接下来在myEdit类里面实现这个函数:

bool MyEdit::event(QEvent *event) 
{
	if (event->type() == QEvent::KeyPress)
	{
		qDebug() << "myEdit event";
		return false;//返回true 就不会继续传递了,设置为false会传递给父类 
	}
};

这个时候会打印出"myEdit event" 和 “parent keyPressEvent”,这是因为在event(QEvent *event) 函数中返回了false,表示这个控件不接收这个事件,那么这个事件就会继续传递到父类去,如果这里接受了事件,那么事件就不会传到父类去了。

4 bool eventFilter(QObject *watched, QEvent *event);

在窗口里面实现eventFilter函数,并给控件安装过滤器

bool CTestWidgetRadius::eventFilter(QObject *watched, QEvent *event)
{
	if (watched == myEdit)
	{
		if (event->type() == QEvent::KeyPress)
		{
			qDebug() << "widget EventFilter";
			return false;
		}
	}
	return QWidget::eventFilter(watched, event);
}
	myEdit = new MyEdit(this);
	myEdit->installEventFilter(this);

这个时候就会打印出
widget EventFilter
myEdit event
parent keyPressEvent
这是因为这里返回了false,表示没有myEdit不接收事件,那么这个事件就会传到event,因为event里面也返回了false,所以这个事件就会传到keyPressEvent(QKeyEvent *event),如果这个函数里面就收了事件,那么事件就停止传递,如果这个函数没有接收,那么这个事件会继续传递到父类。

5 总结

所以事件的传递顺序,是从eventFilter() ->event()-> MyEdit::keyPressEvent(QKeyEvent *event) ->QWidget::keyPressEvent(QKeyEvent *event).这个顺序传递的。当然如果其中一个环节返回了true,事件就终止了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

N-142基于springboot,vue停车场管理系统

开发工具&#xff1a;IDEA 服务器&#xff1a;Tomcat9.0&#xff0c; jdk1.8 项目构建&#xff1a;maven 数据库&#xff1a;mysql5.7 项目采用前后端分离 前端技术&#xff1a;vueelementUI 服务端技术&#xff1a;springbootmybatis-plus 本项目分为普通用户和管理员…

springboot156基于SpringBoot+Vue的常规应急物资管理系统

基于SpringBootVue的常规应急物资管理系统的设计与实现 摘 要 1 ABSTRACT 2 第一章 绪论 3 1.1研究背景 3 1.2研究意义 3 1.3国内外研究现状 4 1.3.1国外研究现状 4 1.3.2国内研究现状 4 1.4研究内容与方法 5 1.4.1研究内容 5 1.4.2研究方法 5 1.5论文的组织结构 5…

管理类联考-复试-英语-听力

文章目录 准备工作1.如何准备英语听力&#xff1f;2.听力学习注意事项一&#xff1a;培养良好的听音习惯&#xff0c;听读顺序要合理3.听力学习注意事项二&#xff1a;边听边记关键词 训练短期记忆能力4.听力学习注意事项三&#xff1a;熟记语篇衔接词把握信息走向5.听力学习注…

Tribon二次开发-tbsetenv.exe和tbunsetenv.exe

通过DOS窗口&#xff0c;输入命令可以添加或删除Tribon环境变量&#xff0c;帮助文档如下&#xff1a; 添加Tribon环境变量 删除环境变量 一般在第三方程序与Tribon交互会用到这种方法&#xff0c;通过调用CMD&#xff0c;输入命令&#xff0c;并将界面隐藏

Linux Centos stream9 mdadm

RAID(Redundant Array of Independent Disk独立冗余磁盘阵列)技术是加州大学伯克利分校1987年提出&#xff0c;最初是为了组合小的廉价磁盘来代替大的昂贵磁盘&#xff0c;同时希望磁盘失效时不会使对数据的访问受损失而开发出一定水平的数据保护技术。RAID就是一种由多块廉价磁…

pnpm安装以及管理多个nodejs版本

官网 https://pnpm.io/zh/ https://www.pnpm.cn/ nodejs安装包 https://nodejs.org/download/release/ windows安装 iwr https://get.pnpm.io/install.ps1 -useb | iex重新打开一个新的控制台&#xff0c;输入pnpm -v ubuntu下安装 curl -fsSL https://get.pnpm.io/insta…

​​​​​​​MD5加密原理

MD5是以512位的分组来处理输入的信息&#xff0c;并且将每一分组又划分成16个32 位的子分组&#xff0c;经过了一系列的处理后&#xff0c;算法的输出由四个32位的分组组成&#xff0c;将这 四个32位的分组结合后将生成一个128位的散列值。详细的MD5加密算法流程如 图6-13所示…

【lesson9】高并发内存池Page Cache层释放内存的实现

文章目录 Page Cache层释放内存的流程Page Cache层释放内存的实现 Page Cache层释放内存的流程 如果central cache释放回一个span&#xff0c;则依次寻找span的前后page id的没有在使用的空闲span&#xff0c;看是否可以合并&#xff0c;如果合并继续向前寻找。这样就可以将切…

oracle数据库索引失效情况总结

场景&#xff1a; 在开发中有时候遇到某个表中的列明明是创建了索引&#xff0c;但查询时却发现索引失效。 环境&#xff1a; 下面是工作流activiti中的两张表act_hi_procinst、act_hi_taskinst关系是一对多&#xff08;一个流程包含多个流程环节&#xff09;&#xff0c;一个…

【乳腺肿瘤诊断分类及预测】基于自适应SPREAD-PNN概率神经网络

课题名称&#xff1a;基于自适应SPREAD-PNN的乳腺肿瘤诊断分类及预测 版本日期&#xff1a;2023-06-15 运行方式: 直接运行PNN0501.m 文件即可 代码获取方式&#xff1a;私信博主或QQ&#xff1a;491052175 模型描述&#xff1a; 威斯康辛大学医学院经过多年的收集和整理&…

使用Python和HTTP代理进行API请求

Python&#xff0c;这个简单易学又功能强大的编程语言&#xff0c;在网络爬虫、数据分析、自动化任务等领域都有着广泛的应用。而当我们需要从外部网站获取数据时&#xff0c;API&#xff08;应用程序接口&#xff09;就成了我们的得力助手。但有时候&#xff0c;某些网站会对A…

机器学习_15_贝叶斯算法

文章目录 1 贝叶斯定理相关公式2 朴素贝叶斯算法2.1 朴素贝叶斯算法推导2.2 朴素贝叶斯算法流程 3 高斯朴素贝叶斯4 伯努利朴素贝叶斯5 多项式朴素贝叶斯6 贝叶斯网络6.1 最简单的一个贝叶斯网络6.2 全连接贝叶斯网络6.3 “正常”贝叶斯网络6.4 实际贝叶斯网络&#xff1a;判断…

陪女朋友学习计算机二级之数据库笛卡尔积和自然连接

数据库中的基本关系运算 交 和数学中的交集类似&#xff0c;但是需要相同的表模式 如果俩个表有相同的关系模式如表1为&#xff08;ID&#xff0c;姓名&#xff0c;学号&#xff09;表2为ID&#xff0c;姓名&#xff0c;学号&#xff09; 表1 表2 交之后就可以变成 并 和数…

SpringBoot数据访问复习

SpringBoot数据访问复习 数据访问准备 引入jdbc所需要的依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency> 原理分析 导入的启动器引入了两个…

计算机软件能力认证考试CCF-202312-1 仓库规划

#自己跑的测试没问题&#xff0c;不知道为啥就是不能满分 原理比较绕&#xff0c;就是让数组中一行不断地与其他行进行比较&#xff0c;最终得到各自的索引 #include <iostream> using namespace std; int main() {int n;int m;cin>>n>>m; int array[n][m];…

点击图形查看

使用zabbix查看监控图像信息&#xff0c;发现会有中文乱码现象。 解决方法如下&#xff1a; 1.拷贝windows文字文件到服务器上 C:\Windows\Fonts目录下拷贝自己需要的中文语言文件 2.修改配置文件 vim /usr/share/zabbix/include/defines.inc.php 81行 define(ZBX_GRAPH_F…

iview DatePicker 日期选择组件在弹窗中使用transfer,导致选择日期弹窗会关闭的问题

背景&#xff1a;在弹窗里面使用日期选择组件&#xff0c;选择组件的面板被弹窗遮挡了部分&#xff0c;所以需要使用transfer属性&#xff0c;但是使用之后组件面板插入body中了&#xff0c;面板的事件会导致弹窗关闭。 解决方案&#xff1a; 添加上transfer属性和指定的date-…

高级FPGA开发之基础协议PCIe

基础协议之PCIe部分 一、TLP包的包头 在PCIe的系统中&#xff0c;tlp包的包头的结构有许多部分是相似的&#xff0c;通过掌握这些常规的包头&#xff0c;能帮助理解在PCIe总线上各个设备之间如何进行数据的收发。 通用的字段 通用字段作用Fmt决定了包头是3DW还是3DW&#xff…

软件测试学习笔记-测试用例的编写

7中测试分类 按照阶段可划分单元测试、集成测试、系统测试、验收测试。代码可见度划分黑盒测试、灰盒测试、白盒测试 单元测试&#xff1a;针对源代码的测试 集成测试&#xff1a;针对接口进行测试 系统测试&#xff1a;针对功能和非功能的测试 验收测试&#xff1a;公测、内测…

中科方德桌面操作系统的安装方法

原文链接&#xff1a;中科方德桌面操作系统的安装方法 大家好&#xff01;继我们之前介绍了如何在VMware Workstation上安装统信UOS、麒麟OS及麒麟信安操作系统之后&#xff0c;今天我为大家带来一篇全新的教程——在VMware Workstation上安装中科方德桌面操作系统的详细步骤。…