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。
需要手动发送。