【QT学习】8.qt事件处理机制,事件过滤器,自定义事件

1.qt事件处理机制

        事件处理:        

        当用户移动鼠标的时候 ,创建一个   鼠标移动事件对象  然后把这个对象放到  事件队列里面去,事件管理器   从队列中 取出事件,然后 调用其对应的事件处理函数

        多态机制:

(1)默认不重写  : 调用  基类的  虚函数函数  处理

(2)重写             : 调用  派生类的  重写后的函数  处理

        一个特例:

        定时器事件    startTimer     每隔 固定时间    创建一个定时器事件对象    不会进入事件队列,直接会触发对应的定时器事件处理函数 timerEvent  去处理。   

2.事件传递的过程

3.QT本身的机制是:

        先NEW出事件对象,放到事件队列里,然后传递给当前对象的event函数,当前对象的event函数(区分类型) 调用 对应的 事件处理函数。

        如果当前对象的event函数没有处理,Return false;就会把事件对象传递给当前对象的父对象的event函数。

2.举例1:

点击label内,label的event事件响应

点击label外,label事件不响应,widget的event响应

1.创建一个label与button,都设置成自定义控件

2.label声明事件,实现事件

3.同样的,widget主页面也是那两个函数

4.结果:

点击label内,label的event事件响应

点击label外,label事件不响应,widget的event响应

3.举例2:(分别)实现以下(三个要求)

(1)label的event事件直接自己处理。

(2)label的event事件调用自身的mousePressEvent(QMouseEvent* e)函数。

(3)label的event事件忽略处理此事件,让主页面处理。

原理:事件分先后,如果处理,后面就不管它了。

总结:event优先级>mousePressEvent

        当前对象event优先级>父对象的优先级

(1)label的event事件直接自己处理。

1.本事件中直接return true;

结果:

(2)label的event事件调用自身的mousePressEvent(QMouseEvent* e)函数。

实现:

 结果:       

(3)label的event事件忽略处理此事件,让主页面处理。

实现:

结果:

二。事件过滤器

事件过滤器(Event Filter)则是一种简单的事件处理机制,它允许一个对象拦截并处理其他对象发出的特定类型的事件。事件过滤器通过重载 QObject 类中的两个函数:bool eventFilter(QObject *obj, QEvent *event) 来实现对事件的拦截和处理。当一个对象发出一个事件时,如果该事件符合当前对象正在拦截的事件类型,那么该对象就会调用 eventFilter() 函数进行处理;否则,它会继续将该事件分发给其他对象。
————————————————

原理说明可看下面文章:

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/SNAKEpc12138/article/details/130850030

1.widget.h

    //注意:字体变《斜》字体,证明此函数有虚继承
void mousePressEvent(QMouseEvent *e);
bool event(QEvent *e);//事件过滤器(*)
bool eventFilter(QObject* obj,QEvent* e);

2.widget.cpp

1.提前安装事件过滤器

2.编写事件函数

//事件过滤器
bool Widget::eventFilter(QObject* obj,QEvent* e){if(obj == ui->label){if(e->type() == QEvent::MouseButtonPress){qDebug() << "事件过滤器中逮到了label的鼠标按下事件";}}else if(obj == ui->pushButton){if(e->type() == QEvent::MouseButtonPress){qDebug() << "事件过滤器中逮到了button的鼠标按下事件";}}return QWidget::eventFilter(obj,e);
}
//事件处理
bool Widget::event(QEvent *e){QEvent::Type  tp = e->type();if(tp == QEvent::MouseButtonPress){qDebug() << "Widget 类里 event函数中 鼠标点击" ;}return QWidget::event(e);
}
//鼠标按下处理函数
void Widget::mousePressEvent(QMouseEvent *event){qDebug() << "Widget 类里 mousePressEvent 函数中 鼠标点击" ;
}

2.运行结果:

注意:

1.widget的eventFilter事件过滤器,return调用(父类,即QWidget)的事件过滤器。这样会继续按qt事件机制运行。

2.(父类,即QWidget)的事件过滤器处理后,根据子对象event优先级>父对象的优先级,需要先调用button的event事件。

三。自定义事件

1.自定义事件类型的Type规定用户使用范围为1000-65535

        在QEvent::Type

2.自建事件其实就是一个(类)

1.myevent事件创建

     //规定自定义事件的type为1000+0x88
const static QEvent::Type myDefinedType = static_cast<QEvent::Type>(QEvent::User + 0x88);//explicit表示构造函数给父类支配
explicit MyDefinedEvent(QString data):QEvent(myDefinedType){m_data = data;
}
QString getData(){return m_data;}

2.widget编写事件与事件过滤器

实现:

bool Widget::eventFilter(QObject* obj,QEvent* e){//qDebug() << "我来也!";if(obj == ui->lineEdit){if(e->type() == MyDefinedEvent::myDefinedType){//把接收到的事件强转下,MyDefinedEvent自建事件其实就是一个(类)MyDefinedEvent* recvEvt = static_cast<MyDefinedEvent*>(e);QString str = recvEvt->getData();qDebug() << "接收到自定义事件:" <<str;ui->lineEdit->insert(str);//需要刷新窗口  重绘窗口的时候才会显示return true;}else{return QWidget::eventFilter(obj,e);}}return QWidget::eventFilter(obj,e);
}
//事件
bool Widget::event(QEvent *e){if(e->type() == QMouseEvent::MouseButtonDblClick){qDebug() << "进来了Widget类中的event";MyDefinedEvent evt("强哥帅");QApplication::sendEvent(ui->lineEdit,&evt);qDebug() << "发送自定义事件";}
}

总结:

        自定义事件就是创建一个类,继承QEvent。

        需要手动发送。

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

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

相关文章

跨考计算机408,小白一定要知道的这件事!

跨考408一定要学好数学&#xff01; 为什么&#xff1f; 因为这是跨考的同学唯一的优势&#xff0c;408是有门槛的&#xff0c;这个门槛包括但不限于&#xff0c;数据结构&#xff0c;计算机组成原理&#xff0c;操作系统等科目&#xff0c;还有编程能力&#xff0c;推理能力…

IEEE PDF eXpress Validating Pdf..之后Error in converting file

在将自己写好的pdf论文转化为IEEE出版的pdf论文格式的时候&#xff0c;错误如下图&#xff1a; 解决办法如下&#xff1a;失败之后&#xff0c;那里有一个选项按钮&#xff0c;叫做manual request&#xff0c;也就是人工转换&#xff0c;点那个申请就可以了&#xff0c;然后也挺…

如何在宝塔中使用命令行执行命令

一、 进入宝塔&#xff0c;找到网站然后点击根目录 二、进入项目中&#xff0c;然后点击 终端 三、如果这里会弹出输入密码的框&#xff0c;那就是需要你输入一下你服务器的 账号密码&#xff0c;然后就登录进去了&#xff0c;可以在这里直接执行命令即可&#xff0c;比如我这里…

TorchEEG文档_学习笔记1【代码详解】

文章目录 一、用户文档1.安装Pytorch2.安装TorchEEG3.安装与图算法的插件 二、教程1.使用TorchEEG完成深度学习工作流程2datasets模块3.transforms模块4.models模块5.trainer模块6.使用Vanilla PyTorch训练模型 一、用户文档 1.安装Pytorch TorchEEG依赖于PyTorch,根据系统、…

git 小记

一、 github新建仓库 git clone 。。。。。。。。。。。 &#xff08;增删查补&#xff0c;修改&#xff09; git add . git commit -m "修改” git push (git push main) 二、branch 分支 branch并不难理解&#xff0c;你只要想像将代码拷贝到不同目录…

Linux操作系统·Linux简介

1.世界上第一个完善的网络操作系统 Unix是1969年由美国电话电报公司(AT&T)贝尔实验室的两个工程师所创造的操作系统&#xff0c;它允许计算机同时处理多用户和程序。目前大型政府单位、大型企业、航空公司、金融机构多在使用&#xff0c;价钱昂贵&#xff0c;但性能和稳定性…

排序之插入排序:从斗地主到插入排序

目录 1.斗地主如何摸牌 2.从摸牌想到插入排序 3.完成插入排序 4.结束语 1.斗地主如何摸牌 不知道各位是否玩过几乎人人都玩过的斗地主游戏呢&#xff1f;相必各位或多或少都玩过一点&#xff0c;再没玩过也看别人打过。今天博主就将从这个游戏为大家讲解我们的插入排序。 在…

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器(TcpServer板块)

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现⾼并发服务器&#xff08;TcpServer板块&#xff09; 一、思路图二、模式关系图三、定时器的设计1、Linux本身给我们的定时器2、我们自己实现的定时器&#xff08;1&#xff09;代码部分&#xff08;2&#xff09;思…

✌粤嵌—2024/4/11—合并区间✌

代码实现&#xff1a; /*** Return an array of arrays of size *returnSize.* The sizes of the arrays are returned as *returnColumnSizes array.* Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().*/// 交换 void swap(i…

UE5、CesiumForUnreal实现建筑白模生成及白模美化功能

1.实现目标 在专栏上篇文章基于GeoJson文件生成城市级白模(本文建筑白模数量12w+)的基础上修改,计算法线和纹理坐标,并基于特定材质进行美化,美化后的白模GIF动图如下所示: 文章目录 1.实现目标2.实现过程2.1 基于Cesium材质美化2.1.1实现原理2.1.2 C++代码2.1.3 蓝图应…

基于SSM+Jsp+Mysql的多人命题系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

免费泛域名SSL如何申请,和通配符有什么区别

-----让我们明确什么是泛域名。所谓泛域名&#xff0c;是指使用星号&#xff08;*&#xff09;作为子域名的占位符&#xff0c;它可以匹配任意子域名。-----而通配符在域名中&#xff0c;它可以出现在主域名的任何位置&#xff0c;它可以用于主域名和子域名的保护。 主要应用场…