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

本文详细解析了Qt中的事件处理机制,包括事件队列的运作、多态在事件处理中的应用、定时器事件的特点、事件传递过程以及如何使用事件过滤器和自定义事件。
摘要由CSDN通过智能技术生成

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。

        需要手动发送。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值