installEventFilter、eventFilter函数理解

installEventFilter函数如下:
void QObject::installEventFilter(QObject *filterObj)

Qt助手的解释如下:

在对象上安装一个事件过滤器filterObj。如下:

monitoredObj->installEventFilter(filterObj);

其中monitoredObj、filterObj都是QObject的子类。上面代码意思是:在monitoredObj对象上安装一个事件过滤器filterObj。该函数一般和如下函数配合使用:

[virtual] bool QObject::eventFilter(QObject *watched, QEvent *event)

注意:该函数是虚函数,也就是说派生自QObject的子类可以重写该函数。

     上面monitoredObj对象安装一个filterObj过滤器后,则可以在filterObj对象所在类的eventFilter函数中拦截发送到monitoredObj对象的事件。如下为KeyPressEater类:


  class KeyPressEater : public QObject
  {
      Q_OBJECT
      ...

  protected:
      bool eventFilter(QObject *obj, QEvent *event) override;
  };

  bool KeyPressEater::eventFilter(QObject *obj, QEvent *event)
  {
      if (event->type() == QEvent::KeyPress) {
          QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
          qDebug("Ate key press %d", keyEvent->key());
          return true;
      } else {
          // standard event processing
          return QObject::eventFilter(obj, event);
      }
  }

现在我们在按钮或QListView两个窗体部件上安装过滤器,如下:


  KeyPressEater *keyPressEater = new KeyPressEater(this);
  QPushButton *pushButton = new QPushButton(this);
  QListView *listView = new QListView(this);

  pushButton->installEventFilter(keyPressEater);
  listView->installEventFilter(keyPressEater);

此时如果在按钮或QListView获取到键盘焦点时按下Esc键,按键事件被 KeyPressEater类的eventFilter函数拦截,从而弹出:

Ate key press 1048576

其中1048576为Esc键的虚拟键码。Qt的QShortcut类就是采取这种技术实现的。

注意:

  • 事件过滤器对象filterObj能阻止(拦截)或放行发向对象monitoredObj的事件。
  • 事件过滤器对象filterObj通过其类的eventFilter函数来接收事件。
  • 如果过滤器对象filterObj所在类的eventFilter函数返回true,则该事件被拦截,也就是原本发向monitoredObj对象的事件不再发向monitoredObj对象;如果过滤器对象filterObj所在类的eventFilter函数返回false,则不拦截该事件,事件依然发向monitoredObj对象。
  • 如果同一个对象上安装多个过滤器,则最后一个过滤器首先被激活调用。
  • 如果在eventFilter函数中删除了接收事件的对象,请确保eventFilter函数返回true,否则Qt将会发送事件到删除的接收对象上,这将导致程序崩溃。
  • monitoredObj对象和filterObj对象必须位于同一个线程中。如果filterObj对象在不同的线程,调用installEventFilter函数则Qt什么都不会做。
  • 如果调用installEventFilter函数后,monitoredObj对象和filterObj对象被移到不同的线程中去了,则eventFilter函数不会被调用,直到monitoredObj对象和filterObj对象回到同一线程时才会被调用。
  • 过滤器对象filterObj所在类的eventFilter函数的第一个参数是被拦截对象monitoredObj,即installEventFilter函数的调用者。以上面的 KeyPressEater例子来说, KeyPressEater类的eventFilter函数的第一个参数是pushButton或listView

     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值