QT事件

  1. 事件处理函数
  2. 事件分发 event()
  3. 事件过滤器 eventFilter()
  4. 事件处理顺序
  5. 引用

Qt 的事件是整个 Qt 框架的核心机制之一

包括很多事件:鼠标事件、键盘事件、大小改变的事件、位置移动的事件等等.

每个事件都对应一个处理函数 mouseEvent(),keyPressEvent()…

如此多的事件处理函数,必定有个地方对其分发 event()

事件处理函数

当重写事件回调函数时,时刻注意是否需要通过调用父类的同名函数来确保原有实现仍能进行!

Qt 的事件对象有两个函数:accept()和ignore().一般很少使用

  1. 如果一个事件处理函数调用了一个事件对象的accept()函数,
    这个事件就不会被继续传播给其父组件
    如果它调用了事件的ignore()函数,Qt 会从其父组件中寻找另外的接受者.

  2. 事件对象默认是 accept 的,而作为所有组件的父类QWidget的默认实现则是调用ignore()。这么一来,如果你自己实现事件处理函数,不调用QWidget的默认实现,
    你就等于是接受了事件;如果你要忽略事件,只需调用QWidget的默认实现。

事件的传播是在组件层次上面的,而不是依靠类继承机制.
(CustomButtonEx的事件传播给了父组件CustomWidget,而不是它的父类CustomButton)

事件分发 event()

event()不负责事件处理,负责把事件分发给对应的事件处理函数(switch)

如果返回值为true,并且设置了accept(),那么qt认为这个事件已经处理完毕,
不会再将这个事件发送给其它对象,而是会继续处理事件队列中的下一事件。

注意:在event()函数中,调用事件对象的accept()和ignore()函数是没有作用的,不会影响到事件的传播.

继承类的event()函数处理之后对应其他事件需要调用父类的的event()函数,否则处理不了其他函数

事件过滤器 eventFilter()

需要先安装对应的事件过滤器

textEdit->installEventFilter(this);

如果一个对象存在多个事件过滤器,那么,最后一个安装的会第一个执行,也就是后进先执行的顺序.

返回true则表示过滤,返回false表示不过滤.保险起见需要调用父类的eventFilter()

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

事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。另外,如果在安装过滤器之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。

事件处理顺序

  1. 重写paintEvent()、mousePressEvent()等事件处理函数.这是最普通、最简单的形式,同时功能也最简单.
  2. 重写event()函数.event()函数是所有对象的事件入口,QObject和QWidget中的实现,默认是把事件传递给特定的事件处理函数.
  3. 在特定对象上面安装事件过滤器.该过滤器仅过滤该对象接收到的事件.
  4. 在QCoreApplication::instance()上面安装事件过滤器.该过滤器将过滤所有对象的所有事件,
    因此和notify()函数一样强大,但是它更灵活,因为可以安装多个过滤器.全局的事件过滤器可以看到 disabled 组件上面发出的鼠标事件.
    全局过滤器有一个问题:只能用在主线程.
  5. 重写QCoreApplication::notify()函数.这是最强大的,和全局事件过滤器一样提供完全控制,
    并且不受线程的限制.但是全局范围内只能有一个被使用(因为QCoreApplication是单例的).(一般不推荐用`)

引用

  1. Qt 学习之路 2(22):事件总结

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至 yangbenbo@whu.edu.cn

文章标题:QT事件

本文作者:杨本泊

发布时间:2020-02-01, 21:46:32

最后更新:2023-07-09, 07:10:11

原始链接:http://yangbenbo.github.io/2020/02/01/QT事件/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录