QT从入门到实战x篇_25_event事件分发器(用于事件的分发;也可以做拦截操作,不建议;bool event(QEvent* e);返回值如果是true代表用户处理这个事件,不向下分发了)

前几篇QT从入门到实战x篇_22_事件:鼠标事件(控件与事件连接),QT从入门到实战x篇_23_定时器实现方法1:事件timerEvent(QTimerEvent* ev),静态变量的作用域,初始化及赋值)介绍了鼠标与定时器事件,本篇将会介绍这些事件内部的机制。

总结:

  1. 用途:用于事件的分发
  2. 也可以做拦截操作,不建议
  3. bool event(QEvent* e)
  4. 返回值如果是true代表用户处理这个事件,不向下分发了
  5. e->type()==鼠标按下

1. event事件分发器


以前面的事件为例,当程序中触发鼠标及计时器事件并不是直接触发,而是需要通过一个 bool event(QEvent* e)的事件分发器来触发对应的事件。其基本模型如下:

在这里插入图片描述
bool event(QEvent* e)的参数为QEvent类,其返回值为bool类型,如果返回的是true,代表用户要处理这个事件,不向下分发事件。

2. 通过event事件分发器拦截事件


根据这一特性可以做事件的拦截操作,例如在鼠标进入时不分发给对应的 mouseMoveEvent中,而是在 bool event(QEvent* e)就处理好了操作。一般不会做如此操作,为了演示效果,下边在事件分发器中做拦截。

在前面的例子中,鼠标移动就会输出坐标值,一旦进入TextLabel中按下和释放鼠标也会有对应的输出。
在这里插入图片描述
此处通过事件分发器拦截鼠标按下事件。

(1)通过查看QEvent类的介绍,查看到其中包含了Qt中所有的event
在这里插入图片描述
在这里插入图片描述
知道对应的鼠标按下事件的枚举值
在这里插入图片描述
(2)对应代码:

  • mylabel.h
    //通过重写event分发器拦截鼠标按下按钮
    bool event(QEvent *e);
  • mylabel.cpp
//通过e来判断鼠标是否按下
bool myLabel::event(QEvent *e)
{
    //如果是鼠标按下,在分发中做拦截操作
    if(e->type()==QEvent::MouseButtonPress)
    {
        //将子类强转为父类
        QMouseEvent* ev=static_cast<QMouseEvent *>(e);
        QString str=QString::fromLocal8Bit("Event::鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
        qDebug()<<str;

        //true代表用户自己处理这个事件,不向下分发
        return true;
    }

    //其他事件交给父类处理 默认处理
    return QLabel::event(e);
}

运行结果:
在这里插入图片描述
上面进行拦截是很少使用的,因为QT中事件是很多的,主要是目的为了表明事件是由分发器进行分发的。

3. 学习视频地址:QT从入门到实战x篇_25_event事件分发器

整体代码如下:

  • mylabel.h
#ifndef MYLABEL_H
#define MYLABEL_H

#include <QLabel>

class myLabel : public QLabel
{
    Q_OBJECT
public:
    explicit myLabel(QWidget *parent = nullptr);

    //鼠标进入事件
    void enterEvent(QEvent *event);

    //鼠标离开事件
    void leaveEvent(QEvent *);

    //鼠标按下
    virtual void mousePressEvent(QMouseEvent *ev);

    //鼠标释放
    virtual void mouseReleaseEvent(QMouseEvent *ev);

    //鼠标移动
    virtual void mouseMoveEvent(QMouseEvent *ev);

    //通过重写event分发器拦截鼠标按下按钮
    bool event(QEvent *e);

signals:

};

#endif // MYLABEL_H
  • mylabel.cpp
#include "mylabel.h"
#include <QDebug>
#include <QMouseEvent>

myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
//设置鼠标追踪状态,默认是false
setMouseTracking(true);
}
//鼠标进入事件
void myLabel::enterEvent(QEvent *event)
{
//    qDebug()<<"鼠标进入";
}

//鼠标离开事件
void myLabel::leaveEvent(QEvent *)
{
//    qDebug()<<"鼠标离开";
}
//鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev)
{
    //当鼠标左键按下,提示信息
//    if(ev->button()==Qt::LeftButton)
//    {
        QString str=QString("鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
        qDebug()<<str;
//    }

}

//鼠标释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev)
{
//    if(ev->button()==Qt::LeftButton)
//    {
        QString str=QString("鼠标释放了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
        qDebug()<<str;
//    }

}

//鼠标移动
void myLabel::mouseMoveEvent(QMouseEvent *ev)
{
    //&为位与运算符,只有在所有状态下均为左键按下时为真
//    if(ev->buttons() & Qt::LeftButton)
//    {
        QString str=QString("鼠标移动了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
        qDebug()<<str;
//    }

}

//通过e来判断鼠标是否按下
bool myLabel::event(QEvent *e)
{
    //如果是鼠标按下,在分发中做拦截操作
    if(e->type()==QEvent::MouseButtonPress)
    {
        //将子类强转为父类
        QMouseEvent* ev=static_cast<QMouseEvent *>(e);
        QString str=QString::fromLocal8Bit("Event::鼠标按下了 x= %1 y=%2 globalx=%3 globaly=%4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
        qDebug()<<str;

        //true代表用户自己处理这个事件,不向下分发
        return true;
    }

    //其他事件交给父类处理 默认处理
    return QLabel::event(e);
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十月旧城

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值