QT程序如何在长时间事件处理中保持界面响应(Qt)
(2010-06-12 03:26:32)
标签:
qt界面响应it |
分类: QT |
摘自姚仰光博士的论文。
在编写QT的界面程序时,当我们调用QApplication::exec()时,我们就启动了QT的事件循环。在开始的时候,QT会发出一些事件来显示和绘制窗口部件。在这之后,事件循环就开始运行,不断地检查是不是有事件发生并且把这些事件发送给应用程序中的QObject。
当一个事件被处理时,其他事件也可能会产生并且追加到QT的事件队列中。如果我们在处理一个特定的事件上耗费过多的时间,用户界面就会变得不能够响应。例如在OCS保存一个观测流程的过程中,一直到文件保存完毕,窗口系统产生的一些事件才会被处理。在保存过程中,这个应用程序就不能响应窗口系统的请求来重绘自己。
一个解决方式是使用多线程:一个处理应用程序用户界面的线程,另外一个执行文件保存的线程。
另一个简单的方法是在事件处理程序中调用QApplication::processEvents()。这个函数告诉QT处理来处理任何没有被处理的事件,并且将控制权返回给调用者。实际上,QApplication::exec()就是一个不停调用QApplication::processEvents()函数的小while循环。这种方式的危险性在于,也许用户在观测流程未保存好之前就关闭了主窗口,或者在界面上通过鼠标或键盘执行了其它的输入,以至于观测流程未保存好就企图被程序使用。对于这个问题的解决办法是把 qApp -> processEvents(); 替换为 qApp -> eventLoop() -> processEvents( QEventLoop::ExcludeUserInput ); 通过这个调用告诉QT忽略鼠标和键盘事件。
当一个事件被处理时,其他事件也可能会产生并且追加到QT的事件队列中。如果我们在处理一个特定的事件上耗费过多的时间,用户界面就会变得不能够响应。例如在OCS保存一个观测流程的过程中,一直到文件保存完毕,窗口系统产生的一些事件才会被处理。在保存过程中,这个应用程序就不能响应窗口系统的请求来重绘自己。
一个解决方式是使用多线程:一个处理应用程序用户界面的线程,另外一个执行文件保存的线程。
另一个简单的方法是在事件处理程序中调用QApplication::processEvents()。这个函数告诉QT处理来处理任何没有被处理的事件,并且将控制权返回给调用者。实际上,QApplication::exec()就是一个不停调用QApplication::processEvents()函数的小while循环。这种方式的危险性在于,也许用户在观测流程未保存好之前就关闭了主窗口,或者在界面上通过鼠标或键盘执行了其它的输入,以至于观测流程未保存好就企图被程序使用。对于这个问题的解决办法是把 qApp -> processEvents(); 替换为 qApp -> eventLoop() -> processEvents( QEventLoop::ExcludeUserInput ); 通过这个调用告诉QT忽略鼠标和键盘事件。