Qt事件过滤器

1. 事件过滤器

void QObject::installEventFilter(QObject *filterObj)
bool eventFilter(QObject *obj, QEvent *event);

        filterObj表示事件筛选器对象,它接收发送到此QObject对象(安装事件过滤器的部件对象)的所有事件。筛选器可以停止事件(返回true),也可以将事件转发给此QObject对象(返回false)。事件过滤器filterObj通过它的eventFilter()函数接收事件。

//举例说明:
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    lineEdit = new MyLineEdit(this);    //在部件A建立部件B,部件A即B的父部件
    lineEdit->move(100, 100);

    lineEdit->installEventFilter(this);   // 在Widget上为lineEdit安装事件过滤器
}
/*
 * 此时filterObj为this:表示窗口部件Widget。Widget接收发送到lineEdit对象的全部事件。
 * 可以这样理解:一个部件安装了事件筛选器对象是其父部件的事件过滤器,则其父部件可以接收其全部事件。
 */

2. 接收事件

        在Qt中,事件过滤器的eventFilter函数返回值表示该事件是否被事件过滤器拦截,即是否停止事件的传递。返回值是一个布尔类型的值:

        1)当返回true时,表示事件已被过滤器拦截,不会传递给被监听的对象进行处理;

        2)当返回false时,事件会继续传递给被监听的对象进行处理。

        3)返回给基类进行处理,例:return QObject::eventFilter(obj, event);可以理解为:没有条件的递归,即死循环递归调用自己)。

按F1打开帮助文档

注意:

        1)eventFilter函数一般会被重写,返回true/false是程序员自己在程序里手动添加的;

        2)return QObject::eventFilter(obj, event)具体值,其实也是每次调用自己,根据是否有手动添加的true/false来决定的。默认不过滤,返回false.

3. 事件的传递(通过4实例中的键盘按下事件举例)

4. 实例

//mylineedit.cpp
#include "mylineedit.h"
#include <QKeyEvent>
#include <QDebug>

MyLineEdit::MyLineEdit(QWidget *parent) :
    QLineEdit(parent)
{

}

void MyLineEdit::keyPressEvent(QKeyEvent *event) // 键盘按下事件
{
    qDebug() << tr("MyLineEdit键盘按下事件");
    QLineEdit::keyPressEvent(event);          // 执行QLineEdit类的默认事件处理
    //事件是先传递给指定窗口部件的,这里确切的说应该是先传递给获得焦点的窗口部件的。但是如果该部件忽略掉该事件,那么这个事件就会传递给这个部件的父部件。
    event->ignore();                          // 忽略该事件
}


bool MyLineEdit::event(QEvent *event)  // 事件
{
    if(event->type() == QEvent::KeyPress)
        qDebug() << tr("MyLineEdit的event()函数");
    return QLineEdit::event(event);   // 执行QLineEdit类event()函数的默认操作
}
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "mylineedit.h"
#include <QKeyEvent>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    lineEdit = new MyLineEdit(this);    //在部件A建立部件B,部件A即B的父部件
    lineEdit->move(100, 100);

    lineEdit->installEventFilter(this);   // 在Widget上为lineEdit安装事件过滤器
}

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

void Widget::keyPressEvent(QKeyEvent *event)
{
    Q_UNUSED(event);
    qDebug() << tr("Widget键盘按下事件");
}

bool Widget::eventFilter(QObject *obj, QEvent *event) // 事件过滤器
{
    if(obj == lineEdit){              // 如果是lineEdit部件上的事件
        if(event->type() == QEvent::KeyPress){
            qDebug() << tr("Widget的事件过滤器");
            }
    }
    return QWidget::eventFilter(obj, event);
}

 测试结果:

总结:

1)只有installEventFilter,没有eventFilter,事件依旧不会被提前捕获接收。必须成对存在。

2)没有event 事件传递依旧成立。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值