QT5|C++|通过创建子线程方式实现进度条更新

背景: 一开始是通过在主线程中写一个for循环,每次加1后睡眠1s进行进度条更新。但这样写的结果是 --> 无法动态显示进度条进度。后通过上一篇文章 **QT5\|C++\|通过信号槽机制实现进度条更新** 中的写信号槽机制实现。实现后 考虑了下有没有其他方式实现,后想到了通过子线程方式。以下是通过子线程实现的具体事例:

cpp 复制代码
功能: 
(1)点击【显示进度条进度】按钮,每隔1s动态加载进度条进度直到加载到100%;
(2)点击【退出】按钮,关闭当前对话框。

1、dialog.cpp

cpp 复制代码
#include "dialog.h"
#include "ui_dialog.h"
#include<QPushButton>
//#include<QThread>
#include<thread>
#include<chrono>
#include<iostream>

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);

    connect(ui->quit_pushButton,&QPushButton::clicked,this,&QDialog::accept);
    ui->progressBar->setRange(1,100);

    std::thread myThread([=]{
        ThreadFunction();
    });
    myThread.detach();

}

void Dialog::ThreadFunction(){
    connect(ui->progressBar_pushButton,&QPushButton::clicked,this,[=]{
        for(auto i =1; i!=101 ;i++){
            ui->progressBar->setValue(i);
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        }
    });
}

Dialog::~Dialog()
{
    delete ui;
}

2、dialog.h

cpp 复制代码
#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

    void ThreadFunction();

private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H

3、main.cpp

cpp 复制代码
#include "dialog.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Dialog w;
    w.show();
    return a.exec();
}

4、Dialog.ui

cpp 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QWidget" name="verticalLayoutWidget">
   <property name="geometry">
    <rect>
     <x>150</x>
     <y>370</y>
     <width>351</width>
     <height>161</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
       <widget class="QPushButton" name="progressBar_pushButton">
        <property name="text">
         <string>显示进度条进度</string>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QPushButton" name="quit_pushButton">
        <property name="text">
         <string>退出</string>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_2">
      <item>
       <widget class="QProgressBar" name="progressBar">
        <property name="value">
         <number>0</number>
        </property>
       </widget>
      </item>
     </layout>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

注意事项:

cpp 复制代码
1、在主线程的for循环中睡眠1s后更新会造成阻塞 不能直接写;
2、关于主线程中的控件,不要在子线程中进行设置,会阻塞主线程。
(关于这一点猜测的原因:qt内部机制 刷新不及时(虽然会阻塞,最终还是会更新完进度)。如果有大神了解具体原因,请详细介绍下,虚心学习)

显示效果:

子线程进度条

相关推荐
RuoZoe16 小时前
从 2026 年 3 月 1 日开源,到 26.10.9:Jalium UI 半年时间到底走了多远?
c语言·c++
鱼子星_18 小时前
【C++】继承和多态(上)
c++·笔记
郝学胜-神的一滴19 小时前
Qt 高级编程 045:坐标体系深度实战
开发语言·c++·windows·python·qt·程序人生
码匠许师傅19 小时前
【设计模式精讲】22.中介者模式(Mediator)
c++·设计模式·软件工程·uml·中介者模式
爱吃巧克力的程序媛1 天前
main.cpp注册 C++ 类到 QML 元对象系统
c++·qt
YYYing.1 天前
【C++进阶系列 (二)】关于线程堆栈的那些事——函数调用过程
开发语言·c++·函数·线程堆栈
键盘会跳舞1 天前
【C++多线程】死锁诊断工具实战:从 Windows 到 Linux 的全链路排查
linux·c++·windows·死锁
HugoStudio_SWAN1 天前
洛谷 P10719 \[GESP202406 五级] 黑白格——暴力美学与图像处理的最小外接矩形
c++·图像处理·人工智能·学习·程序人生·算法·目标跟踪
jimy11 天前
C++ 的 “移动语义”——Move Semantics
开发语言·c++
励志不掉头发的内向程序员1 天前
【LibreCAD 2D架构】从鼠标点击到图形创建:RS_ActionDrawLine交互流程与状态机解析
开发语言·c++·qt·学习·系统架构·计算机外设·交互