在我早期开发的时候,处理循环问题就喜欢用for直接运行到底, 但如果要同时更新界面的输出信息、进度信息,不幸遇到几万次甚至几十万次循环的时候,随便动一下界面就白屏了,界面上其他的操作就完全没法响应。

举个小例子:

void MainWindow::on_btn_print_clicked()
{//清理输出信息ui->textBrowser->clear();//获取打印行数int count = ui->spinBox->value();//设置进度值范围ui->progressBar->setRange(0, count);ui->progressBar->setValue(0);//循环打印for(int i = 0; i < count; i++) {ui->textBrowser->append("最近多次持续40℃以上高温天气,未来一周左右还会继续...");//将数据输出到文件中或是做一些其他操作...//更新进度值ui->progressBar->setValue(i+1);}ui->textBrowser->append("输出完毕...");
}

我们来运行一下demo,看一下效果,这里是GIF截图:

如图所示,随便点一下就卡住了。后来想到用线程处理数据上的操作, 但是UI的打印输出只能在主线程中进行 ,循环太久,主线程还是会卡顿,毕竟CPU不会给一个APP太多的占用时间。后来在别人的开源代码中学到了一个方法,只需要一句话就解决了这个问题。

    //循环打印for(int i = 0; i < count; i++) {ui->textBrowser->append("最近多次持续40℃以上高温天气,未来一周左右还会继续...");//将数据输出到文件中或是做一些其他操作...//更新进度值ui->progressBar->setValue(i+1);//优先响应UI事件,防止卡死, 提升用户体验qApp->processEvents();}

就是这个 qApp->processEvents(), 以下是Qt帮助文档中的描述:

[static] void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents)

Processes all pending events for the calling thread according to the specified flags until there are no more events to process.

You can call this function occasionally when your program is busy performing a long operation (e.g. copying a file).

In the event that you are running a local loop which calls this function continuously, without an event loop, the DeferredDelete events will not be processed. This can affect the behaviour of widgets, e.g. QToolTip, that rely on DeferredDelete events to function properly. An alternative would be to call sendPostedEvents() from within that local loop.

Calling this function processes events only for the calling thread.

Note: This function is thread-safe.

根据指定的标志处理调用线程的所有挂起事件,直到没有更多事件要处理。当您的程序忙于执行长时间操作(例如复制文件)时,您可以偶尔调用此函数。如果您正在运行一个连续调用此函数的本地循环,而没有事件循环,则不会处理 DeferredDelete 事件。这会影响widgets的行为,例如QToolTip,依赖 DeferredDelete 事件才能正常运行。另一种方法是从该本地循环中调用 sendPostedEvents()。调用此函数仅为调用线程处理事件。

优化后, 我们再来看一下运行结果:

打印50W行数据的同时,执行其他操作不会卡住了。

以下是完整的代码:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_btn_print_clicked();void on_btn_stop_clicked();private:Ui::MainWindow *ui;bool print_lock;bool stop_flag;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);print_lock = false;stop_flag = false;
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::on_btn_print_clicked()
{if (print_lock){return;}//防止重复执行print_lock = true;//获取打印行数int count = ui->spinBox->value();//清理输出信息ui->textBrowser->clear();//设置进度值范围ui->progressBar->setRange(0, count);ui->progressBar->setValue(0);//循环打印for(int i = 0; i < count; i++) {ui->textBrowser->append("最近多次持续40℃以上高温天气,未来一周左右还会继续...");//将数据输出到文件中或是做一些其他操作...//更新进度值ui->progressBar->setValue(i+1);//停止if (stop_flag) {break;}//优先响应UI事件,防止卡死, 提升用户体验qApp->processEvents();}if (stop_flag){ui->textBrowser->append("输出中断...");} else {ui->textBrowser->append("输出完毕...");}print_lock = false;stop_flag = false;
}void MainWindow::on_btn_stop_clicked()
{//正在打印中if (print_lock)stop_flag = true;elsestop_flag = false;
}

Qt 流畅的运行大循环相关推荐

  1. Qt Creator指定运行设置

    Qt Creator指定运行设置 指定运行设置 为子项目创建运行配置 指定桌面设备类型的运行设置 指定Valgrind设置 启用调试 指定Android设备的运行设置 指定基于Linux的设备的运行设 ...

  2. QT学习笔记(一):VS2013 +QT 5.8 运行、编译问题解决

    QT学习笔记(一):VS2013 +QT 5.8 运行.编译问题解决 jom: E:\C++\4.QT\HelloWord\Makefile.Debug [debug\moc_predefs.h] E ...

  3. Qt 测量函数运行耗时

    Qt 测量函数运行耗时 本人常用两种方法,在此做记录: 方法一:QTimer (Windows和Linux均可)其精度为ms级 #include <QTime> QTime time; t ...

  4. Qt lnk1158 无法运行rc.exe 解决

    Qt: error lnk1158 无法运行rc.exe 今天运行Qt程序 ,在release模式出现 "error lnk1158 无法运行rc.exe". Qt版本:Qt 5. ...

  5. lua qt 编译_Win32下 Qt与Lua交互使用(一):配置Qt下Lua运行环境

    偶然间看到Lua这种脚本语言,有点兴趣,简单学习了一下.html 发现Lua与C++之间能够实现很是强的交互性.Lua中能够使用C++中的函数,C++中也能够使用Lua中的函数.由此能够引起出不少奇思 ...

  6. vs qt 在linux运行,QT安装以及使用(QT支持linux和windows,也支持C/C++代码的编译运行,比vs简洁多)...

    Windows:linux 0. QT Version qt-win-opensource-4.7.4-mingw qt-creator-win-opensource-2.4.1 1. 系统 Wind ...

  7. Qt一个进程运行另一个进程

    Qt 进程间通信 1. 一个进程运行另一个进程 2. 例程代码 1. 一个进程运行另一个进程 Qt 的 QProcess 类用来启动一个外部程序并与其进行通信. 使用 start() 函数运行一个进程 ...

  8. 2021-05-21 qt程序aas运行失败提示undefined symbol: _Z34QBasicAtomicInt_fetchAndAddOrderedPVii问题

    问题出现场景: 客户机上使用qt4.8.7编译生成的应用程序(客户机上正常运行),放到服务器上运行提示undefined symbol: _Z34QBasicAtomicInt_fetchAndAdd ...

  9. 海思开发板hi3559移植带opengl的qt并成功运行血泪史

    几个必不可少的流程:环境linux系统 1,安装海思交叉编译工具.2,编译qt库,配置qt编译构件,拷贝qt库到板子3,编译海思sdk(为编译gpu做准备).4,编译海思gpu kernel.5,修改 ...

  10. QT 修改应用运行的环境变量

    在QT 应用运行时需要显示加载某个dll,而需要修改系统的环境变量: 增加环境变量: bool AddEnvironmentPath(const QString& strPath) {// 取 ...

最新文章

  1. Multithreading in Java
  2. 015_Redis创建集群
  3. Objective C ARC 使用及原理
  4. java rwd_面向任务的设计-不仅限于Mobile First和RWD
  5. 【转】Dynamics 365 Customer Engagement中插件的调试
  6. 3.8 RIPv2的认证机制
  7. android 叠加视图 重启,android-后台应用程序以侦听拖动手势
  8. c语言经典面试题 洗牌,网易游戏面试题:如何设计一个公平的洗牌算法
  9. Java 网络编程之Socket详解
  10. 计算机显示无法格式化,计算机格式化SD卡提示Windows无法完成格式化解决方法
  11. hiBurn下载-hitool烧写鸿蒙2.0系统到Hi3861V100-从哪里找到芯片列表文件更新芯片列表-HarmonyOS
  12. Win10鼠标单击经常变双击
  13. python人脸识别表情检测器(2):基本框架的制作
  14. vue 自定义事件 传入额外参数
  15. 学会运用爬虫框架 Scrapy各类技术文章大汇总
  16. 空间连续体上接触力的无线传感和定位
  17. codeforces C. Two Teams Composing
  18. Windows命令行关闭IE代理
  19. Ceph 认证授权和RBD块存储、对象存储使用(三)
  20. 2021研报目录更新

热门文章

  1. Qt 窗口嵌入桌面 窗口 放在桌面
  2. VS生成dump文件和调试dump文件
  3. 方块方舟怎么自建服务器,方块方舟新版更新,玩家可自定义单机局域网数值
  4. C++ 基类指针和派生类指针之间的转换
  5. java编程思想读后感
  6. 凤凰系统运行linux,把凤凰系统装进U盘里,打造PC上的可移动android系统
  7. 解决webpack5打包html中图片后图片无法显示问题
  8. webpack打包html中img,打包资源成功,图片引用错误,不能显示问题
  9. 自由职业者互联网进化记
  10. 五大优秀的数据库设计工具