qt在linux下eventFilter,QT的Event Filter

一直对Event Filter似懂非懂, 通过看C++ GUI Programming with Qt4, Second Edition, 争取搞明白. 顺便自己把英文翻译成中文, 算是自己做的笔记了.

Installing Event Filters

QT事件模块一个真正强大的特性是可以设置一个QObject的实例去监测另外一个QObject实例的事件,在被监测的实例see之前.

假设我们有一个CustomerInfoDialog这样的widget, 它由几个QLineEdit组成.我们想用Spacer键来转变focus到下一个QLineEdit.这个非标准的行为可能对一个内部的程序很合适, 需要培训它的用户来使用它. 一个直接的方法是子类QLineEdit,然后重新实现keyPressEvent()来调用focusNextChild(), 像这样:

void MyLineEdit::keyPressEvent(QKeyEvent *event)

{

if (event->key() == Qt::Key_Space)

{

focusNextChild();

}

else

{

QLineEdit::keyPressEvent(event);

}

}

这个方法有一个主要的弊端: 如果我们在这个form中用到几个不同类型的widget(比如QComboBox和QSpinBox), 我们必须也子类化它们来表现出相同的行为. 一个更好的方案是让CustomerInfoDialog来监控它的子widget的按键事件,

在监测的代码里执行需要的行为. 这可以用event Filter来达到. 设置一个event filter有两个步骤:

1. 在目标对象上调用installEventFilter(),将监测对象注册到目标对象上.

2. 在监测对象的eventFilter()方法里处理目标对象的事件.

在ctor里注册监测对象是一个好地方:

CustomerInfoDialog::CustomerInfoDialog(QWidget *parent) :QDialog(parent)

{

...

firstNameEdit->installEventFilter(this);

lastNameEdit->installEventFilter(this);

cityEdit->installEventFilter(this);

phoneNumberEdit->installEventFilter(this);

}

一旦event Filter注册了, 发送到firstNameEdit, lastNameEdit, cityEdit和phoneNumberEdit的事件在被发送到原来的目的地之前, 会先发到CustomerInfoDialog的eventFilter()函数.

这是接收这些事件的eventFilter()函数:

bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event)

{

if (target == firstnameEdit || target == lastNameEdit

|| target == cityEdit || target == phoneNumberEdit)

{

if(event->type() == QEvent::KeyPress)

{

QKeyEvent *keyEvent = static_cast(event);

if (keyEvent->key() == Qt::Key_Space)

{

focusNextChild();

return true;

}

}

}

return QDialog::eventFilter(target, event);

}

首先,我们检查是否目标widget是一个QLineEdit. 如果是个key Press事件, 把它转换为QKeyEvent, 并检查哪个键值被按下.

如果是space, 我们调用focusNextChild()把focus传到focus链上的下一个widget上, 返回true告诉Qt我们已经处理了这个事件. 如果我们返回false, Qt会发送这个event到它原来的目的地,导致一个假的空格被插入到QLineEdit.

如果目标widget不是QLineEdit, 或者这个event不是一个space按键, 我们把控制权传回到基类的eventFilter去. 目标wdiget可以是基类-QDialog正在监测的某个widget.0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,让我来回答您的问题。Qt中的事件过滤器(Event Filter)是一个对象,它可以拦截并处理所有的事件,例如鼠标事件、键盘事件等等。事件过滤器可以用于拦截事件并进行自定义处理,从而实现一些特殊的功能。 在Qt中,事件过滤器是通过重载QObject类的eventFilter方法来实现的。当一个事件发生时,该事件会被发送到QObject对象的event方法中处理。如果该对象设置了事件过滤器,则事件会被先发送到事件过滤器的eventFilter方法中处理。在事件过滤器中,可以对事件进行拦截、修改或者直接处理,并返回一个布尔值来指示是否继续将事件传递给目标QObject对象。 以下是一个简单的示例代码,演示了如何在Qt中使用事件过滤器: ```c++ // 创建一个事件过滤器对象 class MyEventFilter : public QObject { public: explicit MyEventFilter(QObject *parent = nullptr); protected: bool eventFilter(QObject *obj, QEvent *event) override; }; MyEventFilter::MyEventFilter(QObject *parent) : QObject(parent) { } bool MyEventFilter::eventFilter(QObject *obj, QEvent *event) { // 在这里处理事件 if (event->type() == QEvent::MouseButtonPress) { qDebug() << "Mouse button pressed!"; // 返回true表示事件被处理完毕,不会继续传递给目标QObject对象 return true; } // 返回false表示事件继续传递给目标QObject对象 return QObject::eventFilter(obj, event); } // 将事件过滤器对象安装到目标QObject对象上 QObject *targetObject = ...; MyEventFilter *eventFilter = new MyEventFilter(); targetObject->installEventFilter(eventFilter); ``` 在上述代码中,我们创建了一个MyEventFilter类来作为事件过滤器对象。在eventFilter方法中,我们判断了当前事件的类型,如果是鼠标按下事件,则输出一条调试信息,并返回true,表示事件已经被处理完毕。如果不是鼠标按下事件,则返回false,表示事件继续传递给目标QObject对象。 最后,我们将事件过滤器对象安装到目标QObject对象上,这样事件就会先被发送到事件过滤器中进行处理,然后再传递给目标QObject对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值