首页 > 其他分享 >Qt processEvents - 解决线程中事件阻塞(如槽函数被阻塞)

Qt processEvents - 解决线程中事件阻塞(如槽函数被阻塞)

时间:2024-02-06 16:00:13浏览次数:39  
标签:Qt processEvents 处理事件 阻塞 second 线程 函数

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


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,处理事件,阻塞,second,线程,函数
From: https://www.cnblogs.com/renleiguanchashi/p/18009866

相关文章

  • ROS问题: libQt5Core. so.5:无法打开共享对象文件:没有那个文件或目录
    当运行下面命令报错时ros2runturtlesimturtlesim_node错误信息:/opt/ros/foxy/lib/turtlesim/turtlesim_node:errorwhileloadingsharedlibraries:libQt5Core.so.5:cannotopensharedobjectfile:Nosuchfileordirectory最佳答案 我用这个方法,来自h......
  • pyqt的简介与使用说明
    一,概念1,QT是一个强大的工具库,提供可视化窗口,它是基于C++开发的。pyqt和pyside这两个python库使得可以用python来调用QT库。Pyqt出现更早,社区资料更多。二者的主要区别在许可证上。【PyQt有两种许可协议,一种是GPLv3许可协议,另一种是需要授权的商业许可协议,GPLv3许可协议是指,如果的你......
  • JUC【1.原子类、2.锁Lock、3.阻塞队列、4.并发集合容器、5.并发工具类、6.线程池】、
    (JUC简介)转自极客时间1.JUC简介从JDK1.5起,JavaAPI中提供了java.util.concurrent(简称JUC)包,在此包中定义了并发编程中很常用的工具,比如:线程池、阻塞队列、同步器、原子类等等。JUC是JSR166标准规范的一个实现,JSR166以及JUC包的作者是同一个人DougLea。2.原......
  • QT5气象例子
    天气预报:'''项目实战:天气信息查询'''importsysfromPyQt5.QtWidgetsimportQApplication,QMainWindowfromWeatherWinimportUi_FormimportrequestsclassMainWindow(QMainWindow):def__init__(self,parent=None):......
  • pyqt报错、python报错:src/pyaudio/device_api.c:9:10: fatal error: portaudio.h: 没
    报错信息:-DNDEBUG-fwrapv-O2-Wall-fPIC-O2-isystem/home/devil/anaconda3/envs/91/include-fPIC-O2-isystem/home/devil/anaconda3/envs/91/include-fPIC-I/usr/local/include-I/usr/include-I/home/devil/anaconda3/envs/91/include/python3.10-csrc/pyaudio/d......
  • log for qt
    voidcustomMessageHandler(QtMsgTypetype,constQMessageLogContext&context,constQString&msg){Q_UNUSED(context);QStringdt=QDateTime::currentDateTime().toString("dd/MM/yyyyhh:mm:ss");QStringtxt=QString("[%1]......
  • get and build the qt in open source version
    GettingthesourcecodeFirst,cdintothedirectorywhereyouwantthe"qt5"directorytolive.Then,clonethetop-levelQt5gitrepository:$gitclonegit://code.qt.io/qt/qt5.gitor(ifyou'rebehindafirewallandwanttousethehtt......
  • 物联网浏览器(IoTBrowser)-MQTT协议集成和测试
    一、简介MQTT(消息队列遥测传输)是ISO标准(ISO/IECPRF20922)下基于发布/订阅范式的消息协议。它工作在TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件。MQTT是一个基于客户端-服务器的消息发布/订......
  • Qt/C++音视频开发66-音频变速不变调/重采样/提高音量/变速变调/倍速播放/sonic库使用
    一、前言之前在做倍速这个功能的时候,发现快速播放会有滴滴滴的破音出现,正常1倍速没有这个问题,尽管这个破音间隔很短,要放大音量才能听到,但是总归是不完美的,后面发现,通过修改qaudiooutput的采样率,可以规避这个问题,破音不在出现了,但是音调变了,倍速越大变得越快,人声越发不清晰,变得尖......
  • QT 使用 QtCreator 格式化代码
    QtCreator本身默认支持代码格式化,具体格式化快捷键为:Ctrl+i。可以选择部分或全部选择后执行 Ctrl+i操作完成代码格式化。但只限于缩进格式化,不会对大括号位置、小括号前后空格、运算符前后空格等进行格式化操作,显然使用起来并不是那么的舒心。那么如何优雅的实现全......