一、问题的来源与分析

     首先,我们要知道 “为什么Qt Gui 会停止响应?”。简明扼要的说就是:长时间的密集处理或等待阻塞了Qt的事件循环,应用程序不能响应来自窗口系统的事件请求(《C++ Gui Qt4》 P135中有描述)。   那么多长算长呢?一秒钟算长,两秒钟太长。

     其次,“ 何种情形下会发生该问题? ”。可分为两种情形:

     第一,长时间按顺序执行的密集运算,全部计算结束后才能继续执行,如快速傅立叶变换。

     第二,“ 触发 ”了某项操作,该操作完成后才能进行“ 下一步 ”, 所以这里描述的是异步操作,如保存文件操作,服务器等待连接、网络下载等。详细见附注(1).

     私以为两种情形并无明显的概念上的区分,本质是一样的,但两种情形有不同的处理方法,特别是第二种情形, 在Qt框架下 ,用Qt的信号和槽机制往往可以解决阻塞问题,如QTcpServer::newConnection信号通知连接的到来,QIODevice::bytesWritten()与 QIODevice::readyRead()通知文件的读写,它们都是以非阻塞的形式实现相关功能的利器。 而第一种情形,不仅所有的事件循环停止了,信号和槽也暂时被忽视。我们将针对以上两种情形寻找解决方案。

     最后,我们考虑是否可以把这个造成 Qt Gui 停止响应的罪魁祸首大卸八块,即把他拆分成一个个小块,如果可以拆分,那么每块之间是依赖还是独立,如果独立那问题好办,放在不同的位置独立运作,否则,我们只能同步的执行,而最差的结果是——根本无法拆分!!

     总之,考虑以上信息差异,执行不同的解决方案。


二、解决方案

Manual event processing(人工执行事件)

     保持事件循环有一种最基本的方法——让程序去处理 悬挂事件好了 ,处理完了再回来继续我的后续运算,要做到这一点,就要在我的运算代码中间加上处理事件的代码,这句代码就是 QCoreApplication::processEvents();,只要该句代码能够周期性的被执行,就能保持Qt Gui的响应。

//代码来源于上述链接所指向文章