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


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

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

    1、dialog.cpp

    #include "dialog.h"
    #include "ui_dialog.h"
    #include
    //#include
    #include
    #include
    #include
    
    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    2、dialog.h

    #ifndef DIALOG_H
    #define DIALOG_H
    
    #include 
    
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3、main.cpp

    #include "dialog.h"
    
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Dialog w;
        w.show();
        return a.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4、Dialog.ui

    <?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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    注意事项:

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

    显示效果:

    子线程进度条

  • 相关阅读:
    MySQL MHA高可用配置及故障切换
    并发之Synchronized说明
    【阅读论文】-- IDmvis:面向1型糖尿病治疗决策支持的时序事件序列可视化
    35.cuBLAS开发指南中文版--cuBLAS中的Level-2函数hbmv()
    动态TopicModel BERTopic 中文 长文本 SentenceTransformer BERT 均值特征向量 整体特征分词关键词
    C++ 内联和嵌套命名空间
    基于沙猫群优化算法的线性规划求解matlab程序
    缓存滚动位置:解决keep-alive组件缓存滚动位置失败问题
    For Further Reference
    elasticsearch8.2集群部署
  • 原文地址:https://blog.csdn.net/u011735367/article/details/133011725