前因:
当调用QApplication::exec()时,就启动了QT的事件循环。在开始的时候QT会发出一些事件命令来显示和绘制窗口部件。
在这之后,事件循环就开始运行,它不断检查是否有事件发生并且把这些事件发生给应用程序的QObject。
当处理一个事件时,也可能同时产生一些其他的事件并且将其追加到QT的事件队列中。如果在处理一个特定事件上耗费的事件过多,那么用户界面将变得无法响应。例如,在应用程序把一个文件保存到磁盘的过程中,直到文件保存完毕,才会处理那些由窗口系统产生的事件;在文件保存的过程中,应用程序就不能响应来自窗口系统重新绘制的请求。
起因:如果处理一个特定任务上耗费的时间过多时,那么用户界面就会变得无法响应。
问题:怎么保持在程序密集响应时,界面不会卡住?
在此种情况下的解决方案:
一、利用processEvents()函数
在代码中频繁调用该函数即可QApplication::processEvents()。这个函数告诉QT处理所有那些还没有被处理的各类事件,然后将控制权返回给调用者。 实际上,QApplication::processEvents()就是一个不停调用processEvent()函数的while循环。
示例:
void test::writeFile(const QString &sFileName)
{
QFile f(sFileName);
……
for(int i=0;i<size;i++)
{
代码
qApp->processEvent();
}
}
使用这个方法的时候存在一个潜在的问题:应用程序还在执行的时候,就关闭了主窗口或者点击了其他响应,会产生预料不到的后果。解决方案:替换成QApplication::processEvents(QEventLoop::ExcludeUserInputEvents); 以告诉QT忽略鼠标事件和键盘事件。
补充:QMetaObject::invokeMethod()使用解决界面卡住问题
例如:
二、使用多线程(QT开启多线程有3种方式)
一个线程用于处理应用程序中的用户界面,另一个线程则执行文件保存操作(或任意其他耗时的操作),这样的话,在保存文件的时候,应用程序的用户界面仍可以保持响应。
原文链接:https://blog.csdn.net/ligare/article/details/124498542