event和eventFilter

一.QEvent事件拦截

QEvent事件返回的值是true,则可以拦截其它事件,比如mousePressEvent等事件。

Qt中所有事件均是由QEvent分发下去的。

事件对象创建完毕后, Qt 将这个事件对象传递给QObject 的 event() 函数。 event() 函数并不直接处理事件,而是将这些事件对象按照它们不同的类型,分发给不同的事件处理器( event handler)。 
event() 函数主要用于事件的分发。 
所以,如果你希望在事件分发之前做一些操作,就可以重写这个 event() 函数了。例如,我们希望在一个 QWidget 组件中监听 tab 键的按下,那么就可以继承 QWidget,并重写它的 event() 函数,来达到这个目的: 
这里写图片描述

使用 QEvent::type() 函数可以检查事件的实际类型,其返回值是 QEvent::Type类型的枚举。我们处理过自己感兴趣的事件之后,可以直接返回 true,表示我们已经对此事件进行了处理;对于其它我们不关心的事件,则需要调用父类的 event() 函数继续转发,否则这个组件就只能处理我们定义的事件了。

Qt 是使用 QEvent::type() 判断事件类型,然后调用了特定的事件处理器。


//前面存在事件重写函数
void myLabel::mousePressEvent(QMouseEvent *ev)
{
...
}

/*
*此处用于拦截事件
*/
bool myLabel::event(QEvent *event)
{
if(event->type()==QEvent::MouseButtonPress)
{

...
return true;//表示  鼠标按下  用户自己处理
}
//其它事件  交给父类处理
returun QLabel::event(event);
}

二、eventFilter() 
QObject 有一个 eventFilter() 函数,用于建立事件过滤器。这个函数的签名如下:

  virtual bool QObject::eventFilter(QObject* watched, QEvent* event);
  • 1

eventFilter有两个参数,1个是对象,1个是时间,可以通过事件是什么类型,什么对象来处理。

事件过滤器的原理:它会检查接收到的事件。如果这个事件是我们感兴趣的类型,就进行我们自己的处理;如果不是,就继续转发。这个函数返回一个 bool 类型,如果你想将参数 event 过滤出来,比如,不想让它继续转发,就返回 true,否则返回 false。事件过滤器的调用时间是目标对象(也就是参数里面的 watched 对象)接收到事件对象之前。也就是说,如果你在事件过滤器中停止了某个事件,那么, watched 对象以及以后所有的事件过滤器根本不会知道这么一个事件。

eventFilter() 函数相当于创建了过滤器,然后我们需要安装这个过滤器。安装过滤器需要调用QObject::installEventFilter() 函数。这个函数的签名如下:

 void QObject::installEventFilter(QObject* filterobj);
  • 1

这个函数接受一个 QObject * 类型的参数。记得刚刚我们说的, eventFilter() 函数是 QObject的一个成员函数,因此,任意 QObject 都可以作为事件过滤器(问题在于,如果你没有重写eventFilter() 函数,这个事件过滤器是没有任何作用的,因为默认什么都不会过滤)。已经存在的过滤器则可以通过 QObject::removeEventFilter() 函数移除。

事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。

注意,如果你在事件过滤器中 delete 了某个接收组件,务必将函数返回值设为 true。否则,Qt 还是会将事件分发给这个接收组件,从而导致程序崩溃。

猜你喜欢

转载自blog.csdn.net/weixin_41882459/article/details/111568529