百度了一会,发现没太有文字讲这件事情,因此整理成文字记录一下。


processEvents介绍

长时间运行的操作可以调用processEvents() 保持应用程序响应能力。

void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents)
根据指定的条件为调用线程处理一些待处理事件flags
void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int ms)
处理调用线程的待处理事件(Pending Events)达ms毫秒,或直到没有更多事件需要处理,以较短者为准。

关于ms参数的解释(来自GPT-3.5):

  • 如果正在处理事件的时间超过了指定的时间限制 ms,processEvents 函数仍然会等待事件处理完成,然后返回。
  • 如果事件处理完成前的时间限制 ms 达到了,那么 processEvents 函数将立即返回,即使事件队列中仍有待处理的事件。
  • 此处不太好验证,官方文档也没详写,经博主本人分析,gpt解释的合理

注意:
调用此函数时,线程切换去处理事件时,之前正在做的操作就被阻塞了,直到待处理事件完成。


问题代码及解决方法

问题代码:线程中有死循环,导致没有机会处理事件,执行槽函数。

解决方法:放开注释。使用QCoreApplication::processEvents();

// Work类的槽函数:

// 先触发这个槽函数,里面有while循环,会卡住线程
void Worker::doWork()
{
qDebug() << __FUNCTION__ << " Thread ID: " << QThread::currentThreadId() << "\n"; // 循环10次,每次1s
int i = 1;
while (i < 10)
{
i++;
Sleep(1000);
qDebug() << "second : " << i << " s\n"; //QCoreApplication::processEvents(); //
}
} // 再触发这个槽函数,会因为线程在做while循环,没有机会得到执行
void Worker::doWork2()
{
qDebug() << __FUNCTION__ << " Thread ID: " << QThread::currentThreadId();
} ---------------------------------------------------------------------------------------------------------- // Main函数中的代码
auto *worker = new Worker;
_workerThread = new QThread(this);
worker->moveToThread(_workerThread); // worker的槽函数都在_workerThread线程中执行 connect(this, SIGNAL(operate()), worker, SLOT(doWork(int)));
connect(this, SIGNAL(operate2()), worker, SLOT(doWork2(int))); // 启动线程
_workerThread->start(); emit operate(); // 先让线程中的while循环跑起来
emit operate2(); // 再触发doWork2槽函数,但是因为子线程中doWork在while循环,
// 此事件没有机会被处理,直至while循环结束才得到doWork2执行的机会。
结果1:
注掉QCoreApplication::processEvents(); 阻塞情况: Worker::doWork Thread ID: 0x4260 second : 2 s
second : 3 s
second : 4 s
second : 5 s
second : 6 s
second : 7 s
second : 8 s
second : 9 s Worker::doWork2 Thread ID: 0x4260
结果2:
放开注释 QCoreApplication::processEvents(); 解决阻塞问题后: Worker::doWork Thread ID: 0x4260 second : 2 s Worker::doWork2 Thread ID: 0x4260 // 执行processEvents时,如果有事件被阻塞了,立刻执行其槽函数 second : 3 s
second : 4 s
second : 5 s
second : 6 s
second : 7 s
second : 8 s
second : 9 s

Qt processEvents - 解决线程中事件阻塞(如槽函数被阻塞)的更多相关文章

  1. PyQt(Python+Qt)学习随笔:exit code 1073741845与槽函数所在对象不能定义同名实例方法问题

    最近做了几次测试,在PyQt中如果使用与槽函数同名的实例方法可能会导致不可控的错误. 案例1:如果两个信号映射到同名的槽函数,虽然参数不一样,但真正响应的槽函数是最后定义的槽函数,具体案例请见< ...

  2. 关于Qt在子线程中使用QMessageBox的折衷方法

    Qt将所有GUI相关的处理都限制在主线程中,这么做有助于防止意想不到的访问冲突产生,但也限制了线程中某些简单的UI交互的实现,比如QMessageBox. 因为QMessageBox必须在主线程中打开 ...

  3. PyQt(Python+Qt)学习随笔:Qt Designer中连接Action和槽函数

    在Designer中试了半天,终于找到了Action添加槽函数的方法,操作步骤: 在Designer右边界面中点击鼠标右键 确保信号/槽编辑被勾选,如图是未勾选的情况:. 勾选后会出现信号和槽的编辑界 ...

  4. 完美解决ListView中事件ItemCreated中使用ClientID导致插入数据失败

    于昨天晚上看到视频做到这个例子,但是发现始终有错误,在ListView的ItemCreated事件中使用了ClientID则会导致数据插入数据库失败.当点击插入按钮时,网页就像点击F5刷新一样,无任何 ...

  5. 使用Python+Qt时解决QTreeWidget中的内容超出边界后自动隐藏的问题

    问题: 默认情况下,内容超出边界后会自动省略,以...代替,而且无法出现水平滚动条 解决方法: 把VerticalScrollBar和HorizontalScrollBar的值都设为ScrollBar ...

  6. 解决iScroll中事件点击一次却触发两次的问题

    var t1=null;//全局 function myClick() { if (t1 == null){ t1 = new Date().getTime(); }else{ var t2 = ne ...

  7. QT paintevent 事件, update()槽函数

    一界面重载函数 使用方法: 1在头文件里定义函数 protected: void paintEvent(QPaintEvent *event); 2 在CPP内直接重载 void ---------- ...

  8. Qt发送一次信号触发两次槽函数的原因

    在手动为控件编写槽函数的时候,如果将槽函数名字按如下格式编辑,则不需要再次进行手动关联 void on_pushButton_1_clicked(); void on_radioButton_clic ...

  9. 重点:怎样正确的使用QThread类(很多详细例子的对比,注意:QThread 中所有实现的函数是被创建它的线程来调用的,不是在线程中)good

    背景描述: 以前,继承 QThread 重新实现 run() 函数是使用 QThread唯一推荐的使用方法.这是相当直观和易于使用的.但是在工作线程中使用槽机制和Qt事件循环时,一些用户使用错了.Qt ...

  10. promise 的基本概念 和如何解决js中的异步编程问题 对 promis 的 then all ctch 的分析 和 await async 的理解

    * promise承诺 * 解决js中异步编程的问题 * * 异步-同步 * 阻塞-无阻塞 * * 同步和异步的区别? 异步;同步 指的是被请求者 解析:被请求者(该事情的处理者)在处理完事情的时候的 ...

随机推荐

  1. the server responded with a status of 413 (Request Entity Too Large) 解决

    前端上传文件,本地测试好的,放到服务器上出现了这个错误:the server responded with a status of 413 (Request Entity Too Large) 问题原 ...

  2. 神经网络优化篇:详解Adam 优化算法(Adam optimization algorithm)

    Adam 优化算法 在深度学习的历史上,包括许多知名研究者在内,提出了优化算法,并很好地解决了一些问题,但随后这些优化算法被指出并不能一般化,并不适用于多种神经网络,时间久了,深度学习圈子里的人开始多 ...

  3. Mysql 中 not in 的查询优化

    本文为博主原创,转载请注明出处: 最近做性能优化时,通过开启 MySQL 的慢日志查询配置,发现 有一条慢sql,在这里记录下分析和优化的过程. 该慢 sql 如下: select id from f ...

  4. 【VSCode】秒下vscode

    有时从vscode官网下载速度奇慢甚至失败,介绍一种方法可以秒下 进入官网选择要下载的版本 像我的电脑,下载网址根本打不开 修改下载网址,替换下载地址中红框字符串:vscode.cdn.azure.c ...

  5. 【MicroPython】生成micropython版本头文件 - py\makeversionhdr.py

    用法 $ python makeversionhdr.py mpversion.h 实现 带git仓 get_version_info_from_git 使用git指令:   git describe ...

  6. 【SHELL】查找包含指定字符串的目录、在找出的路径中找出指定格式的文件、并统计出数量

    查找包含字符串"skull"的目录.在找出的路径中找出格式".c/.cpp/.h"的文件.并统计出数量 find . -path ./out -prune -o ...

  7. 【Altium Designer】五颜六色标识的PCB布板(增强PCB可视化特性)

    出现上图中五颜六色的网络标识,对比各个网络会更加清晰,实现步骤如下 打开或关闭  View--->Net Color Override Active   快捷键     F5 设置 displa ...

  8. Go-并发-Go程和信道

  9. [转帖]Linux禁用CPU省电状态/Linux系统性能调优

    https://www.jianshu.com/p/945168b47487 How to Disable CPU Power Saving States on a Redhat or Suse Li ...

  10. [转帖]超线程 Smt 究竟可以快多少?

    https://www.51cto.com/article/686171.html 刚才我们关闭SMT是把CPU10-CPU19全关了,只留下每对里面的1个CPU,也就是留下了CPU0-CPU9. 默 ...