QT:如何在程序密集响应时,界面不会卡住?

前因:
当调用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

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
case 4: LED_A_GPIO->ODR = led_display[i] & 0x01 ? LED_A_PIN : 0; LED_B_GPIO->ODR = led_display[i] & 0x02 ? LED_B_PIN : 0; LED_C_GPIO界面调用show()卡死通常是因为show()方法会引起窗口重绘,而重绘操作->ODR = led_display[i] & 0x04 ? LED_C_PIN : 0; LED_D_GPIO->ODR =通常涉及到复杂的计算和绘图,如果界面复杂或者数据量大,会导致show led_display[i] & 0x08 ? LED_D_PIN : 0; LED_E_GPIO->ODR = led_display[i] & 0x10 ? LED_E_PIN : 0; LED_F_GPIO->ODR = led_display[i] & 0x()方法执行缓慢,甚至卡死程序。 为了解决这个问题,你可以考虑在show()方法中20 ? LED_F_PIN : 0; LED_G_GPIO->ODR = led_display[i] & 0x40 ? LED_G使用Qt的信号与槽机制,将复杂的计算和绘图操作放到槽函数中,然后通过_PIN : 0; LED_DP_GPIO->ODR = led_display[i] & 0x80 ? LED_DP_PIN : 0信号来触发槽函数执行。这样可以避免show()方法执行缓慢,保证界面的流畅性; break; case 5: LED_A_GPIO->ODR = led_display[i] & 0x01 ? LED_A。 另外,你还可以考虑在界面加载就完成计算和绘图操作,然后将计算结果_PIN : 0; LED_B_GPIO->ODR = led_display[i] & 0x02 ? LED_B_PIN : 0; LED_C_GPIO->ODR = led_display[i] & 0x04 ? LED_C_PIN : 0; LED_D和绘图结果缓存起来,在show()方法中直接显示缓存的结果。这样可以避免每次调_GPIO->ODR = led_display[i] & 0x08 ? LED_D_PIN : 0; LED_E_GPIO->ODR用show()方法都需要重新计算和绘图,提高程序的执行效率。 如果以上方法都不能解决你 = led_display[i] & 0x10 ? LED_E_PIN : 0; LED_F_GPIO->ODR = led_display[i的问题,建议你提供更具体的代码和错误信息,这样我才能更好地帮助你解决问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值