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); }

京公网安备 11010502036488号