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