背景: 一开始是通过在主线程中写一个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内部机制 刷新不及时(虽然会阻塞,最终还是会更新完进度)。如果有大神了解具体原因,请详细介绍下,虚心学习)
显示效果:
子线程进度条