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


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. vue项目使用el-table实现无限滚动

    https://blog.csdn.net/weixin_44994731/article/details/107980827 1.安装el-table-infinite-scroll yarn ad ...

  2. 我让 ChatGPT 化身为全知全能的文档小助理,啥姿势她都会......

    ChatGPT 虽然只是一个对话型人工智能,但已经震惊了全世界,有人甚至认为人工智能的奇点已经到来.未来一定会有很多人失业,从工业革命开始,每出现一次重大的技术变革,就必然会有一批人失业,我们要直面现 ...

  3. Qt开发-共享内存使用范例,配合开发者密钥使用后台调试程序或者进入调试模式

    共享内存 就之前不是开发了一个Leventure_DeveloperKey用以调试程序嘛,在这里简单聊一下调试模式的方案. 这里的调试分为了两种,一种是调试模式,一种是开发者模式.需要这两种模式的原因 ...

  4. 如何将接口的返回值中所需信息提取出来作为其他接口的入参使用(postman与jmeter的使用)

    一.背景: 偶尔会用到一个场景,两个接口之前的调用有依赖关系,将其中一个的返回参数中的部分信息取出来作为入参在第二个接口中使用,代码内是比较好实现,只要定义一个变量,用于参数传递. 如果是测试过程中使 ...

  5. 在 CMake 中使用 Qt windeploy 进行 install

    install(TARGETS app BUNDLE DESTINATION . LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINA ...

  6. 操作系统OS笔记2

    操作系统OS笔记2 调度和死锁 调度简介 1. 调度的基本概念 2. 调度原则 调度算法 平均周转时间: 平均带权周转时间:周转时间/服务时间 1. 先来先服务调度算法(FCFS) 当在高级调度中采用 ...

  7. 一文搞清楚Java中的包、类、接口

    写在开头 包.类.接口.方法.变量.参数.代码块,这些都是构成Java程序的核心部分,即便最简单的一段代码里都至少要包含里面的三四个内容,这两天花点时间梳理了一下,理解又深刻了几分. Java中的包 ...

  8. 02-VS调试以及Qt基本使用

    VS调试以及Qt基本使用 1.汇编语言 1.1 VS中C语言嵌套汇编代码(了解) #include <stdio.h> int main() { //定义整型变量a, b, c int a ...

  9. 【SHELL】百分比进度指示,原地踏步

    百分比进度指示,原地踏步效果实现主要利用退格'\b',同行'\c' #!/bin/bash function percentage_progress() { progress=$(($1*100/$2 ...

  10. PHPCMS V9安装出现DNS解析失败的解决方法-不支持采集和保存远程图片

    目前因为phpcms官网停止解析后,很多人安装phpcms v9出现如下错误:     这是因为检测dns解析的域名是phpcms官网的域名,官网域名停止解析后肯定检测失败.解决方法如下:   打开/ ...