事件对象创建完毕后,Qt将这个事件对象传递给QObject的event函数。event函数不直接处理事件,而将这些事件对象按照他们不同的类型,分发给不同的事件处理器。
注意在event函数中,调用事件对象的accept和ignore函数是没有用的,不会影响到事件的传播。
event()函数有一个QEvent对象作为参数,也就是需要转发的事件对象,返回值是bool类型,如果传入的事件已经被识别并且处理,则需要返回true,否则返回false。如果返回值是true,并且该事件对象设置了accept,那么Qt会认为这个事件已经被处理完毕,不会再将这个事件发送给其他对象,而是会继续处理事件队列中的下一事件。
对于不关心的事件,需要调用父类的event函数继续转发,否则这个组件就只能响应我们自己定义的事件了。
事件过滤器:
virtual bool object::eventFilter(QObejct *watched, QEvent *event);
这个函数返回一个bool值,如果你想将参数event过滤出来,比如,不想让它继续转发,就返回true,否则返回false。
void QObejct::installEventFilter(QObject *filterObj);安装过滤器
我们可以向一个对象上面安装多个事件过滤器,只要调用多次installEventFilter()函数。如果一个对象存在多个事件过滤器,那么最后一个安装的会第一个执行。
如果你在事件过滤器中,delete了某个接收组件,务必将函数返回值设为true。否则,Qt还是会将事件分发给这个接收组件,从而导致程序崩溃。事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。另外,如果在安装过滤器之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。
如果要实现全局的事件过滤器,则可以安装到QApplication或者QCoreApplication上面。这里注意,如果使用installEventFilter()函数给一个对象安装事件过滤器,那么该时间过滤器只对该对象有效,只有这个对象的事件需要先传递给事件过滤器的eventFilter进行过滤,其他对象不受影响。如果给QApplication对象安装事件过滤器,那么该过滤器程序中的每个对象都有效。
Qt事件的调用最终都会追溯到QCoreApplication::notify()函数。
virtual void QCoreApplication::notify(QObejct *receiver, QEvent *event);
事件的分发既可以是同步的,又可以是异步的,而函数的调用或者说是槽的回调总是同步的。事件的另一个好处是它可以使用过滤器。
qt中自定义事件非常简单,同其他类库的使用很相似,都是要继承一个类进行扩展。(QEvent)
我们的自定义事件类型不能和已经存在的type值重复,否则会有不可预料的事情发生。qt定义了两个边界:
QEvent::User和QEvent::MaxUser。
static int QEvent::registerEventType(int hint = -1); //解决自定义事件相互之间覆盖的问题
Qt两种事件的发送方式:
1, static bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event);
直接将event事件发送给receiver接收者。在事件被发送的时候,event事件并不会被销毁。通常我们会在栈上创建event对象。
2,static void QCoreApplication::postEvent(QObject* receiver, QEvent* event);
将event事件及其接受者一同追加到事件队列中,因为post事件列会持有事件对象,并且在其post时将其delete掉,因此我们必须在堆上创建event对象。
处理自定义事件:重写 void QObject::customEvent(QEvent *event);