(十三)事件分发器——event()函数,事件过滤

Posted xiangtingshen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(十三)事件分发器——event()函数,事件过滤相关的知识,希望对你有一定的参考价值。

技术图片

事件分发器——event()函数

事件过滤

事件进入窗口之前被拦截 eventFilter 

技术图片
#include "mywidget.h"
#include "ui_mywidget.h"
#include <QDebug>

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    // 给MyLabel 安装事件过滤器
    // 参数 谁来过滤label 的事件
    ui->mylabel->installEventFilter(this);
    ui->label_2->installEventFilter(this);
}

MyWidget::~MyWidget()
{
    delete ui;
}

void MyWidget::mousePressEvent(QMouseEvent *)
{
    qDebug() << "+++++++++++++";
}

bool MyWidget::eventFilter(QObject *obj, QEvent *e)
{
    // 判断对象
    if (obj == ui->mylabel) {
        // 过滤事件
        if (e->type() == QEvent::MouseMove)
        {
            ui->mylabel->setText("++++++++++");
            return true;
        }
    }
    if (obj == ui->label_2) {
        if (e->type() == QEvent::MouseMove)
        {
            ui->label_2->setText("**********");
            return true;
        }
    }
    // 执行默认处理
    return QWidget::eventFilter(obj,e);
}
mywidget.cpp
技术图片
#include "mylabel.h"
#include <QMouseEvent>
#include <QTimerEvent>
#include <QTimer>
#include <QEvent>

// QWidget 默认是不追踪鼠标事件的
MyLabel::MyLabel(QWidget *parent) : QLabel(parent)
{
    // 设置窗口追踪鼠标键
    this->setMouseTracking(true);

    // 启动定时器
    // 参数 1: 触发定时器的时间, 单位: ms
    // 参数2: 使用默认值
    // 返回值: 定时器ID
    id = startTimer(2000);
    id1 = startTimer(3000);


    // 第二种定时器用法
//    QTimer * timer = new QTimer(this);
//    timer->start(100);
//    connect(timer, &QTimer::timeout, this, [=]()
//    {
//        static int number = 0;
//        this->setText(QString::number(number++));
//    });


}

// 进入还是离开边界的一瞬间来完成的
// 鼠标进入
void MyLabel::enterEvent(QEvent *)
{
    setText("你不要在我身上乱摸!!!!");
}

// 鼠标离开
void MyLabel::leaveEvent(QEvent *)
{
    setText("终于离开了...");
}

void MyLabel::mousePressEvent(QMouseEvent *ev)
{
    // 字符串拼接 QString().arg()
    // %1, %2, %3 -- 占位符
    QString btn;
    if(ev->button() == Qt::LeftButton)
    {
        btn = "LeftButton";
    }
    else if(ev->button() == Qt::RightButton)
    {
        btn = "RightButton";
    }
    else if(ev->button() == Qt::MidButton)
    {
        btn = "MidButton";
    }
    QString str = QString("MousePree[%3]:(%1, %2)").arg(ev->x()).arg(ev->y()).arg(btn);

    setText(str);
}

void MyLabel::mouseReleaseEvent(QMouseEvent *ev)
{
    QString btn;
    if(ev->button() == Qt::LeftButton)
    {
        btn = "LeftButton";
    }
    else if(ev->button() == Qt::RightButton)
    {
        btn = "RightButton";
    }
    else if(ev->button() == Qt::MidButton)
    {
        btn = "MidButton";
    }
    QString str = QString("MouseRelease[%3]:(%1, %2)").arg(ev->x()).arg(ev->y()).arg(btn);

    setText(str);
}

void MyLabel::mouseMoveEvent(QMouseEvent *ev)
{
    QString btn;
    if(ev->buttons() & (Qt::LeftButton | Qt::RightButton))
    {
        btn = "LeftButton";
    }
    else if(ev->buttons() & Qt::RightButton)
    {
        btn = "RightButton";
    }
    else if(ev->buttons() & Qt::MidButton)
    {
        btn = "MidButton";
    }
    QString str = QString("MouseMove[%3]:(%1, %2)").arg(ev->x()).arg(ev->y()).arg(btn);

    setText(str);
}

// 每触发一次定时器, 进入该函数中
void MyLabel::timerEvent(QTimerEvent *e)
{
    QString str;
    if(e->timerId() == id)
    {
        static int num = -100;
        str = QString("%1: %2").arg("Time out: ").arg(num++);
        if(num >= 100)
        {
            // 关闭定时器
            killTimer(id);
        }

    }
    else if(e->timerId() == id1)
    {
        static int num1 = 10000;
        str = QString("%1: %2").arg("Time out: ").arg(num1++);
        if(num1 >= 10000+1000)
        {
            // 关闭定时器
            killTimer(id1);
        }
    }


    setText(str);
}

bool MyLabel::event(QEvent *e)
{
    // 返回值
    // true -- 代表事件被处理了,不再继续下发,停止了
    // false -- 事件没有被处理,会继续向下分发
    // 大概的处理步骤
//    switch(e->type()){
//        case QEvent::MouseMove:
//            mouseMoveEvent(e);
//            break;
//        case QEvent::Timer:
//            timerEvent(e);
//            break;
//    }

    // 过滤定时器事件
    if (e->type() == QEvent::Timer) {
        return true;// return false,将事件抛给父类
    }
//    else if (e->type() == QEvent::MouseMove) {
//        return true;
//    }
    else if (e->type() == QEvent::MouseButtonPress) {
        return false;
    }
    // 让父类执行默认的处理
    return QLabel::event(e);
}
mylabel.cpp
技术图片
#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

namespace Ui {
class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = nullptr);
    ~MyWidget();
    void mousePressEvent(QMouseEvent *);
    bool eventFilter(QObject *obj, QEvent *e);
private:
    Ui::MyWidget *ui;
};

#endif // MYWIDGET_H
mywidget.h
技术图片
#ifndef MYLABEL_H
#define MYLABEL_H

#include <QWidget>
#include <QLabel>

class MyLabel : public QLabel
{
    Q_OBJECT
public:
    explicit MyLabel(QWidget *parent = nullptr);
    void enterEvent(QEvent *);
    void leaveEvent(QEvent *);
    void mousePressEvent(QMouseEvent *ev);
    void mouseReleaseEvent(QMouseEvent *ev);
    void mouseMoveEvent(QMouseEvent *ev);
    void timerEvent(QTimerEvent *e);
    bool event(QEvent *e);
private:
    int id;
    int id1;
signals:

public slots:
};

#endif // MYLABEL_H
mylabel.h

 

以上是关于(十三)事件分发器——event()函数,事件过滤的主要内容,如果未能解决你的问题,请参考以下文章

Qt消息机制和事件

12事件

MySQL从入门到精通50讲(二十三)-EVENT事件

installEventFilter可以安装到任何QObject的子类,并不仅仅是UI组件。事件过滤器和安装过滤器的组件必须在同一线程,在它们分属在不同线程时,事件过滤器也是不起作用的

qt源码解析1--事件循环原理(重写事件函数,事件过滤器等)

设计模式——分发器模式