QT ⑥ 事件处理&过滤器

一、QEvent类

  • QEvent是所有事件类的基类(并且是抽象类)

  • 事件流程:

    Widget产生事件————>QObject::event————>判断事件类型————>事件处理器(处理事件)

  • 带过滤器的事件流程:

    产生事件————>过滤器(过滤不关心的事件)————>event判断类型————>事件处理

二、事件示例

头文件

​ 要处理事件就要去重写某类事件的函数

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QKeyEvent>    //按键信息头文件
#include <QMouseEvent>  //鼠标信息
#include <QLabel>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    //1.重写特定事件处理器
    void keyPressEvent(QKeyEvent *e);
    //2.鼠标移动
    void mouseMoveEvent(QMouseEvent *e);
    //3.鼠标按键按下
    void mousePressEvent(QMouseEvent *e);
    //4.重写基类 event虚函数
    bool event(QEvent *e);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H
 

cpp文件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //将要筛选的控件注册到当前类的过滤器 eventFilter中,
    //这样控件上产生的任何事件,优先提交给eventFilter处理
    ui->pushButton_2->installEventFilter(this);
    ui->pushButton_3->installEventFilter(this);
}

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

//重写   参数: e 表示当前按下信息的按键信息  首地址
void Widget::keyPressEvent(QKeyEvent *e)
{
    //key() 获取当前事件产生时的按下按键的信息
    switch(e->key())
    {
    case Qt::Key_W:
    {
        ui->pushButton->move(ui->pushButton->x(),ui->pushButton->y()-10);
        break;
    }
    case Qt::Key_S:
    {
        ui->pushButton->move(ui->pushButton->x(),ui->pushButton->y()+10);
        break;
    }
    case Qt::Key_A:
    {
        ui->pushButton->move(ui->pushButton->x()-10,ui->pushButton->y());
        break;
    }
    case Qt::Key_D:
    {
        ui->pushButton->move(ui->pushButton->x()+10,ui->pushButton->y());
        break;
    }
    }
}

void Widget::mouseMoveEvent(QMouseEvent *e)
{
    //ui->pushButton->move(e->pos());
    ui->pushButton->move(e->x() - ui->pushButton->width()/2,e->y() - ui->pushButton->height()/2);
}
//鼠标点击
void Widget::mousePressEvent(QMouseEvent *e)
{
    int w = ui->pushButton->width();
    int h = ui->pushButton->height();
    //判断鼠标左右键
    if(e->button() == Qt::LeftButton)
    {
        ui->pushButton->resize(w+=10,h+=10);
    }
    else if(e->button() == Qt::RightButton)
    {
        ui->pushButton->resize(w-=10,h-=10);
    }
    ui->pushButton->setStyleSheet(QString("background-color:blue;border-radius:%1;").arg(w/2));
    ui->pushButton->move(e->x() - w/2,e->y() - h/2);
}

//重写基类
bool Widget::event(QEvent *e)
{
    //qDebug() << "================打印================";

    //判断事件类型
    if(e->type() == QKeyEvent::KeyPress)
    {
        //手动在基类内调用keyPressEvent()函数
        keyPressEvent(static_cast<QKeyEvent *>(e));
        //也可以直接在基类event内写算法
        return true;
    }
    if(e->type() == QMouseEvent::MouseMove)
    {
        mouseMoveEvent(static_cast<QMouseEvent *>(e));
        return true;
    }
    if(e->type() == QMouseEvent::MouseButtonPress)
    {
        mousePressEvent(static_cast<QMouseEvent *>(e));
        return true;
    }
    //其余事件交给基类处理
    return QWidget::event(e);
}


三、过滤器

​ 使用过滤器,有两个参数,一个是Object (关注的控件) ,另一个是QEvent 事件类型

​ 需要将控件添加到过滤器中才可以进行过滤器操作

头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QKeyEvent>    //按键信息头文件
#include <QMouseEvent>  //鼠标信息
#include <QLabel>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    //重写事件过滤器
    bool eventFilter(QObject *obj , QEvent *e);
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

cpp文件

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //将要筛选的控件注册到当前类的过滤器 eventFilter中,
    //这样控件上产生的任何事件,优先提交给eventFilter处理
    ui->pushButton_2->installEventFilter(this);
    ui->pushButton_3->installEventFilter(this);
}

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

//过滤器
bool Widget::eventFilter(QObject *obj, QEvent *e)
{
    //判断事件是否是某个控件上产生
    if (obj == ui->pushButton_2)
    {
        //判断控件上产生的事件是否为想要处理的事件
        if(e->type() == QMouseEvent::MouseButtonPress)
        {
            //进行处理
        }
    }
    //判断控件
    if(obj == ui->pushButton_3)
    {
        //判断事件类型
        if(e->type() == QMouseEvent::MouseButtonPress)
        {
            //处理操作
        }
    }
    //其他非关注事件,都提交给基类处理
    return QWidget::eventFilter(obj,e);
}