当QPaintEvent事件送达时会调用QWidget::paintEvent函数,这个虚函数将作为本事件的处理器做出适当响应,这里的响应是重绘窗口。QWidget中的event函数将绝大多数常用类型事件传递给特定的事件处理器,如mousePressEvent、keyPressEvent、paintEvent等,并且忽略了其他类型的事件。
QT事件模型中一个功能是一个QObject实例可以监视另一个QObject实例中的事件,实现方法是在目标对象中安装事件过滤器。这样事件过滤器将在事件到达目标对象之前首先获取该事件,从而起到监视目标对象事件的效果。
假设希望通过使用”空格键“把焦点移到下一个QPushButton。对于这种非标准行为的一种解决方法是继承QPushButton,然后重新实现keyPressEvent来调用focusNextChild();
代码如下:
void MyQpushButton::keyPressEvent(QKeyEvent* event)
{
if(event->key()==Qt::Key_Space)
focusNextChild();
else
QPushButton::keyPressEvent(event);
}
这种方法的缺点,如果存在各种各样不同的的窗口部件,就不得不逐个继承它们,然后分别进行功能扩展。另一个解决方法是事件过滤器,可以在父窗口中监视全部子窗口的事件,方法是在父对象中注册的过滤器中添加扩展功能的代码。设置事件过滤器需要2个步骤:
1、通过对目标对象调用installEventFilter来注册监视对象;
2、在监视对象的eventFilter函数中处理目标对象的事件;
当程序存在大量长时间IO操作时,用户界面可能冻结而无法响应。解决办法有3种:
1、多线程;
2、在处理耗时事件时频繁调用QApplication::processEvents();
该函数告知QT处理任何没有被处理的事件,并且将控制权返回给调用者。实际上QApplication::exec()就是一个不停调用processEvent函数的小while循环。
qApp->eventLoop()->processEvents(QEventLoop::ExcludeUserInput);//告知QT忽略鼠标和键盘事件
3、推迟耗时事件处理;
这种方式是通过使用定时器来实现的。通过一个特定的”0毫秒定时器“来实现。