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内部机制 刷新不及时(虽然会阻塞,最终还是会更新完进度)。如果有大神了解具体原因,请详细介绍下,虚心学习)

显示效果:

子线程进度条

相关推荐
南境十里·墨染春水13 小时前
C++ 工厂模式:从入门到进阶,彻底掌握对象创建的艺术
开发语言·c++·算法
小白舒_SC13 小时前
多个VS版本的Qt VS Tools的QtMsBuild不兼容问题
经验分享·qt
一拳一个呆瓜16 小时前
【STL】_SCL_SECURE_NO_WARNINGS
c++·stl
小小编程路17 小时前
C++ 异常 完整讲解
开发语言·c++
Frank学习路上20 小时前
【C++】面试:关键字与语法特性
c++·面试
金色熊族20 小时前
QTransform使用心得(二)--仿射变换、非仿射变换、矩阵
qt·线性代数·矩阵
Irissgwe21 小时前
数据结构-栈和队列
数据结构·c++·c·栈和队列
点云侠21 小时前
PCL 生成三棱锥点云
c++·算法·最小二乘法
.道阻且长.1 天前
C++ string 操作指南:接口解析
java·c语言·开发语言·c++
laplaya1 天前
使用 vcpkg 管理 C++ 项目中的依赖
开发语言·c++