一、Qt 的事件处理,有五个层次:
1. 重写
paintEvent()
、mousePressEvent()
等事件处理函数。这是最普通、最简单的形式,同时功能也最简单。2. 重写
event()
函数。event()
函数是所有对象的事件入口,QObject
和QWidget
中的实现,默认是把事件传递给特定的事件处理函数。3. 在特定对象上面安装事件过滤器。该过滤器仅过滤该对象接收到的事件。
4. 在
QCoreApplication::instance()
上面安装事件过滤器 app.installEventFilter() 。该过滤器将过滤所有对象的所有事件,因此和notify()
函数一样强大,但是它更灵活,因为可以安装多个过滤器。全局的事件过滤器可以看到 disabled 组件上面发出的鼠标事件。全局过滤器有一个问题:只能用在主线程。5. 重写
QCoreApplication::notify()
函数。这是最强大的,和全局事件过滤器一样提供完全控制,并且不受线程的限制。但是全局范围内只能有一个被使用(因为QCoreApplication
是单例的)。
这几个层次的事件处理方式的 调用顺序 ,5 --> 4 --> 3 --> 2 --> 1
二、界面假死现象
循环事件阻塞带来的最大问题就是造成界面假死,长时间没有事件响应,系统的窗口管理程序就会建议用户强制停止程序(应该都遇到过这种问题)。
解决该问题方法有三种(参考文献2):这里我们只讲和事件循环有关的两种就解决方法;
1、如果长时间任务是一个回调函数或循环体 就可以在函数内部使用qApp->processEvents; 强制分发事件。该方法问题:可能导致递归。
解决:qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
2、自己实例化一个QEventloop类 开启一个本地事件循环。 一样的问题:也是可能导致递归
参考文献: