Qt实现 在Thread子线程里处理耗时业务

Qt 如何处理耗时的线程,不影响主线程响应 QApplication::processEvents) 处理一些跟界面无关的但耗时的事情,这些事情跟界面在同一个线程中,由于时间太长,导致界面无法响应,处于“假死”状态。查了一下 qApp->processEvents();会优先响应主线程(UI线程);前些时间遇到一个问题,在主线程接收子线程读的数据,一直接收不到,但放在子线程没有问题;后面查了一下,因为接收子线程使用了 qApp->processEvents();该函数的作用是让程序处理那些还没有处理的事件,然后再把使用权返回给调用者。在这种情况下,有一种方法是使用多线程,即在子线程中处理文件保存; 阅读详情

目录

1、QThread

2、何时使用线程

3、不使用多线程会有什么现象

4、使用线程处理耗时操作

5、线程退出注意点


做应用软件,因为主界面的原因,业务线程可以说​极其重要。如果不开线程的话,软件很难做到流畅,一个卡顿的软件很难被用户买单。

很多初学者会被线程的同步机制给吓到,或者觉得加锁会影响性能,所以干脆会拒绝对线程的使用。

但是合理和高效的使用线程,以及对多线程的掌握程度,往往又决定了软件的性能以及面试的结果和定级​。

因为单纯就应用软件方向而言,如果面试者对线程很陌生,面试官其实也基本可以判定,面试者日常中所负责的只是基础的增删改查业务,而不具备项目的​整体把控能力。

为什么说要掌握线程,​以及线程的同步机制呢。因为很多处理过程,都是耗时的操作,如果都让主线程来处理,软件主界面会不堪重负。

比如用户点击了一个生成报表按钮,如果数据量很大,不是几秒钟就能做好的,这时候用户又点击了另外一个设置按钮,然后设置界面等了​1-2秒才能弹出来,会极大降低​体验。

如果在设计之初,就把可能的耗时任务都放到不同的子线程去处理,处理完毕后,再通过回调或者信号机制通知主线程,就不会影响到主界面​,所以搭建一个稳定、合理的线程池是一件有必要去​做的事情。

如果同步机制做不好,可能就会出现资源抢占、死锁等问题,造成软件卡死​。所以说为了开发出稳定的软件和功能,更需要掌握线程,以及多线程的同步机制​。

幸运的是,很多框架都已经搭建好了现有的线程类或者线程池,如果使用框架,就不需要我们自己去写原生的多线程,提高了开发效率​。

下面一起了解一下如何在qt中,创建子线程处理耗时操作​。

1、QThread

QThread类提供了一种独立于平台的方式来管理线程。一个QThread对象管理一个线程。

子线程在run()函数中开始执行,通过start()启动线程,通过quit()和wait()来退出线程。

2、何时使用线程

当需要处理比较耗时的操作,不希望影响到主界面的操作时,就可以考虑使用线程,来承接那部分耗时的任务,

比如我们在布局上显示4个视频,如果在主线程渲染,那么主界面马上就吃不消了,用户点击操作界面将会十分卡顿。

3、不使用多线程会有什么现象

下面我在主线程模拟了一段耗时的代码,以模拟视频渲染,当点击开始的按钮后,进入耗时操作:

void Form::on_pushButton_clicked()
{
    //模拟解码耗时操作
    int cnt=0;
    while (cnt<50) {
        cnt++;
        qDebug()<<"run main"<<"cnt="<<cnt;
        QThread::msleep(300);
    }
}

界面现象:

这时界面卡主,用户虽然可以操作,但是很卡顿,甚至软件有时候会直接卡死,就需要等耗时循环结束,界面才恢复正常。

但是这往往不是我们希望的效果,于是请出线程,来帮助处理,分担压力。

4、使用线程处理耗时操作

#ifndef WORK_H
#define WORK_H

#include <QObject>
#include <QThread>
#include <QDebug>

class Work:public QThread
{
    Q_OBJECT
public:
    Work():_stop(true)
    {
    }
    ~Work(){
        qDebug()<<"thread start quit";
        _stop = false;
        QThread::quit();
        QThread::wait();
        qDebug()<<"thread success!";
    }

    void run() override
    {
        //模拟解码耗时操作
        int cnt=0;
        while (cnt<50 && _stop) {
            cnt++;
            qDebug()<<"run Thread"<<"cnt="<<cnt;
            QThread::msleep(300);
        }

    }

private:
    bool _stop;
};

#endif // WORK_H

work类继承自QThread,重写父类的QThread的run方法,在run方法中,延时300毫秒,模拟耗时操作。

在btn中启动线程:

void Form::on_pushButton_clicked()
{
    //模拟解码耗时操作
//    int cnt=0;
//    while (cnt<50) {
//        cnt++;
//        qDebug()<<"run main"<<"cnt="<<cnt;
//        QThread::msleep(300);
//    }

    if(_w)
        _w->start();
}

通过调用start()函数,启动子线程,即会调用run方法,进行处理。

界面效果正常:

 

5、线程退出注意点

使用以下,先quit,再wait。

QThread::quit();
QThread::wait();

因为quit()函数虽然是用来停止QThread的,但是由于Qt本身拥有事件循环机制,所以在调用完quit()后,QThread可能还没有停止。

所以在执行quit()后,通常调用wait()来等待QThread子线程的结束,即run函数的结束,这样才能保证在释放QThread的时候,它的子线程是完全停止运行的状态。

Qt中主线程与子线程之间操作的问题 Qt中主线程与子线程之间操作的问题 今天在工作的时候遇到一个Qt中关于多线程的问题,困扰了半天时间,在同事的帮助下解决了,因此来记录一下,以免下次在遇到时又一脸懵,也供像我一样的小白借鉴。好与不好请勿乱评,正在学习中的小白一枚。。 问题: 在主线程中创建工作线程(一个while循环测试)后,想单击暂停按钮进行暂停操作和继续按钮继续执行操作,建立信号与槽的关系,工作线程可以正常执行,但暂停按钮发送消息后,暂停槽一直没有执行,代码如下: 有三个类:用A(主),B(线程类),C(工作执行类)代替 A.cpp: v 阅读详情

相关推荐

Qt Creator中使用qthread处理耗时操作的新手教程

在Qt Creator里,直接在主线程执行耗时任务会导致界面卡死。用QThread开启子线程能有效解耦逻辑与UI,让程序保持响应。本篇手把手带你从继承QThread、重写run()到安全传递数据,避开常见崩溃陷阱,真正掌握QThread的实用技巧。

weixin_36282234的博客 102

QT中程序运行耗时的计算方法

版本:QT5.12.10 方法1:QElapsedTimer 接口: void QElapsedTimer::start() qint64 QElapsedTimer::elapsed() const 使用示例: QElapsedTimer ElapsedTimer; ElapsedTimer.start(); /*耗时操作......*/ qDebug()<<"耗时"<<ElapsedTimer.elapsed()<<"毫秒"; 方法2:QTime,与QElaps

wwplh5520370的博客 7080

Qt Creator环境下qthread应用的深度剖析

在Qt Creator中驾驭QThread,不只是start()和quit()那么简单——从线程安全、信号槽跨线程传递,到moveToThread模式与QThreadPool的适用边界,手把手拆解常见崩溃与假死根源。聚焦QThread生命周期管理与对象归属权,让并发逻辑真正稳如磐石。

weixin_36328210的博客 141

QT程序段耗时检测

QT程序段耗时检测

无名的博客 1247

QT与Unity3D跨进程通信:基于TCP/IP与心跳机制的稳定实现方案

在跨平台应用开发中,进程间通信(IPC)是实现模块化与协同工作的关键技术。其核心原理在于通过操作系统提供的机制,在不同进程间安全、高效地交换数据。TCP/IP协议栈作为网络通信的基础,提供了可靠、有序的字节流传输能力,是实现跨进程、跨主机通信的通用方案。在工程实践中,基于TCP/IP的Socket通信能够有效解决传统IPC方式(如共享内存、管道)在跨平台兼容性、稳定性方面的不足,尤其适用于需要处理复杂业务逻辑与实时3D渲染的异构系统集成场景。通过设计自定义的应用层协议(如消息头+消息体结构)并嵌入心跳机制,

weixin_30781107的博客 413

qthread新手教程:从创建到运行的完整指南

深入讲解QThread的使用方法,从线程创建到实际运行为新手提供完整操作流程。通过实例解析帮助理解QThread的核心机制,让多线程编程更简单高效。

weixin_35370061的博客 575

qt实现线程方式有哪些

Qt 实现线程5 种方式继承 QThread 重写 run ()moveToThread ()(官方推荐)QRunnable + 线程池高级封装模式项目标准用法:moveToThread大量小任务:QRunnable 线程池简单临时任务:QtConcurrent入门学习:继承 QThread注意:线程 run () 函数中可以发信号通知结束,但必须调用 exec () 开启事件循环,否则信号槽无法工作。QtConcurrent::run 默认没有事件循环 → 不能直接用信号槽。

雪的季节 489

基于Qt与YOLOv8的模块化工业视觉检测系统设计与实现

目标检测是计算机视觉的核心任务之一,旨在识别图像中的物体并定位其位置。其原理通常基于深度学习模型,通过卷积神经网络提取特征并预测边界框与类别。在工业领域,目标检测技术能实现自动化缺陷识别、产品分类与定位,大幅提升质检效率与一致性。然而,从算法原型到稳定部署常面临模型迭代频繁、系统耦合度高、跨平台适配等工程挑战。为此,采用模块化软件架构成为关键解决方案,它将系统拆分为图像采集、预处理、推理引擎、后处理与可视化等独立模块,通过标准化接口降低耦合。本文以工业视觉检测为应用场景,深入探讨如何基于Qt框架与YOLOv

weixin_34226182的博客 286

QHotkey多线程使用指南:如何在子线程中安全注册全局热键

QHotkey 是目前 Qt 桌面开发中最常用的全局热键(global hotkey)库,它能让应用在最小化、失焦甚至完全隐藏时依然响应快捷键,非常适合托盘程序、后台工具和插件系统。很多开发者希望把全局热键的注册放到子线程中,避免阻塞 UI,但 QHotkey 多线程使用存在不少隐性规则,稍不留神程序就会在退出时挂起。这份 QHotkey 多线程使用指南,将从线程模型原理讲起,带你掌握在子线程中安

gitblog_00057的博客 1050

C++基础到Qt实战:从语法到桌面应用开发的完整能力跃迁

C++作为一门经典的面向对象编程语言,其核心在于对内存管理、对象生命周期和标准库的高效运用。理解RAII(资源获取即初始化)原则、智能指针和移动语义等现代C++特性,是构建健壮、高性能应用程序的基础。这些底层原理为开发图形用户界面(GUI)应用提供了坚实支撑。Qt框架正是C++在GUI开发领域的威力放大器,它通过信号与槽机制、元对象系统等设计,极大简化了跨平台桌面应用的开发流程。掌握Qt不仅需要理解其事件循环、父子对象内存管理等核心概念,更要将C++的面向对象思想与Qt的组件化设计相结合。本文通过一个完整的

dengjuanshou7445的博客 819

通过引入线程池提升QT程序的并发性能

在程序开发过程中,开发者总是想尽可能的充分利用计算机的硬件性能来提升程序的执行效率。为了达到这个目标我们会尽可能多的引入多线程来提升程序的并发性能。在QT程序中我们也可以通过引入多线程来提升程序的执行效率,但是在引入多线程的时候,要对项目架构进行严格的设计,避免出现死锁、僵尸线程甚至卡死界面的情况。 包含线程池的QT项目的一般架构如下图所示: JobWidget对象存在于UI线程中,负责计算结果呈现和与用户的交互操作。 JobManager对象存在于JobManager线程中,该线程负责计算任务的

yang1fei2的博客 2030

QT跨线程信号槽连接:原理、实战与性能优化

信号与槽机制是QT框架实现对象间通信和解耦的核心技术,其本质是基于元对象系统的事件驱动模型。在单线程环境下,直连方式可同步调用槽函数;但在多线程场景中,必须通过事件队列实现线程间安全通信,这涉及线程亲和性、参数序列化等关键原理。掌握跨线程连接对于构建响应式、高并发的桌面应用或服务模块具有重要技术价值,能有效避免界面卡死、数据竞争等常见问题。在实际工程中,开发者需根据场景在自动连接、队列连接等类型间做出正确选择,并关注参数注册、对象生命周期管理等细节。本文聚焦QT多线程编程中的信号槽连接,深入解析其工作机制、

weixin_30475039的博客 378

C++的std::future使用

1、头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QDebug> #include <QDomDocument> using namespace std; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public:

我不是码农的博客~~~ 644

Qt从入门到精通:信号槽机制、环境搭建与实战计算器开发

C++ GUI开发是构建桌面应用程序的核心技能,其关键在于理解事件驱动与对象间通信机制。在众多框架中,跨平台解决方案因其能大幅降低多系统适配成本而备受青睐。信号与槽(Signals & Slots)作为一种类型安全、松耦合的通信范式,为GUI组件交互提供了优雅解耦方案,极大提升了代码可维护性。元对象系统(Meta-Object System)通过编译时扩展,为这一机制提供了运行时内省能力,是Qt框架的基石。这些技术共同支撑了从工业控制软件到嵌入式设备界面的广泛应用。本文聚焦于Qt框架,通过环境搭建详解与计算

weixin_33816946的博客 379

基于Qt的雷达数据采集系统:TCP/UDP网络编程与实时处理实践

网络编程是构建分布式数据采集与控制系统的核心技术,其核心在于根据数据特性选择合适的传输协议。TCP协议提供面向连接、可靠有序的传输,适用于对准确性要求极高的控制指令;而UDP协议则以其无连接、低延迟的特性,更适合处理高速、实时的数据流,如雷达原始ADC数据。在工程实践中,通过TCP实现稳健的指令控制链路,结合UDP构建高速数据管道,能够有效支撑远程硬件操控与海量数据回传。这种架构在嵌入式系统、工业自动化及物联网领域具有广泛应用价值。本文以TI AWR1843雷达与DCA1000采集卡为具体案例,深入探讨了如

weixin_30932215的博客 426

CUDA编译踩坑实录:如何正确设置-gencode参数适配你的GPU算力

本文深入解析CUDA编译中-gencode参数的核心原理与实战配置,帮助开发者解决常见的'Unsupported gpu architecture'错误。通过厘清虚拟架构与真实架构的区别,并提供多版本兼容的CMake配置方案,确保编译出的代码能精准适配不同GPU算力,兼顾性能与广泛兼容性。

weixin_28829903的博客 338

一文彻底搞懂 Qt 多线程

本文深入解析了Qt多线程的核心概念与常见问题。首先指出Qt多线程的本质是"线程+事件循环+对象归属线程",强调必须同时理解操作系统线程、事件循环和对象线程归属这三个关键点。文章详细分析了QThread的角色定位,澄清它不是工作线程本身而是线程控制器,并重点介绍了官方推荐的Worker-Object模式及其优势。同时解释了为什么moveToThread()比继承QThread更受推崇,以及事件循环对Qt对象工作的重要性。最后还剖析了跨线程信号槽的工作原理,帮助开发者避免界面卡顿等问题。全文

m0_37859235的博客 533

一文读懂无人机AI识别算法,原理、技术、应用

本文详细介绍了无人机识别算法的工作原理、技术优势以及在多个行业的应用前景,展现了其在提升安全监控、资源管理和应急响应中的关键作用。尽管无人机识别算法在多个领域展现出巨大潜力,但仍面临技术挑战,如算法的准确性、数据的实时处理能力以及对复杂环境的适应性。4. 消防与城市管理: 无人机识别算法在消防和城市管理中的应用,为相关部门提供了及时的信息支持,提升了应急处置能力和城市管理水平。1. 公安监控: 无人机识别算法在公安领域的应用,可以实时识别犯罪嫌疑人和违法行为,有效提升城市治安管理的智能化水平。

foiadrone的博客 1847

5.1Qt中多线程的使用

在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑, 如果只有一个线程去处理,就会导致窗口卡顿,无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件,其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验还可以提升程序的执行效率。在qt中使用了多线程,有些事项是需要额外注意的:默认的线程在Qt中称之为窗口线程,也叫主线程,负责窗口事件处理或者窗口控件数据的更新。

丰锋的博客 211

域格4G网优模块获取

1、获取当前小区信息 接口说明 该命令用于获取当前小区信息。 语法结构 命令类型 格式 返回结果 Execute AT+SCELLINFO +SCELLINFO: <cellMode>,<mcc>,<mnc>,<lac>,<cellId>,<afrcn>,<cpi>,<rxLevel>

自由的幻想 2463

嵌入式状态机编程-QP状态机框架与常见状态机方法

状态机基本术语 现态:是指当前所处的状态。 条件:又称为“事件”,当一个条件被满足,将会触发一个动作,或者执行一次状态的迁移。 动作:条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必需的,当条件满足后,也可以不执行任何动作,直接迁移到新状态。 次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就转变成新的“现态”了。 传统有限状态机Fsm实现方法 如图,是一个定时计数器,计数器存在两种状态,一种为设置状态,一种为计时状态 设

qq_36969440的博客 9663

QT系列(五)

在进行桌面应用程序开发的时候, 假设应用程序在某些情况下需要处理比较复杂的逻辑如果只有一个线程去处理,就会导致窗口卡顿无法处理用户的相关操作。这种情况下就需要使用多线程,其中一个线程处理窗口事件其他线程进行逻辑运算,多个线程各司其职,不仅可以提高用户体验还可以提升程序的执行效率。默认的线程在Qt中称之为窗口线程,也叫主线程,有时候也称之ui线程负责窗口事件处理或者窗口控件数据的更新子线程负责后台的业务逻辑处理,子线程中不能对窗口对象做任何操作,这些事情需要交给窗口线程处理。

m0_57794197的博客 1187

【树莓派安装Homeassistant及基本配置】

时隔一年,我又重新开始玩Homeassistant,发现其中奥妙无穷,惊喜不断。在我浅薄的认知中要学好嵌入式,必须玩过Homeassistant,并且玩出自己的名堂!因为这是最贴切实际的生活应用没有之一,每月更新使得唯有活水来;拥抱大千使得永葆青春的活力;鬼斧神工的操作精彩纷呈,可以堪称软件与硬件的完美落地!

vor234的博客 1万+
上一篇: 大白话描述如何理解多线程
下一篇: 使用ubuntu18遇到的一些坑
Qt上位机开发
Qt上位机开发 领域专家: C/C++技术领域 领域专家: C/C++技术领域
博客等级 码龄9年 9664粉丝 178原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值