QT Thread 练习Demo

 1 #ifndef THREADTEST1_H
 2 #define THREADTEST1_H
 3 
 4 #include <QObject>
 5 #include <QThread>
 6 #include <QDebug>
 7 #include <QRandomGenerator>
 8 #include <QWaitCondition>
 9 #include <QMutex>
10 #include <QSemaphore>
11 
12 class ThreadTest1 : public QThread
13 {
14     Q_OBJECT
15 public:
16     ThreadTest1(int _index, QWaitCondition *_condition, QMutex *_mutex, QSemaphore *_semaphore, QObject *parent = nullptr);
17     ~ThreadTest1();
18 signals:
19     void updateProgress(int);
20 
21 public:
22     void doSomething();
23 
24     void run() override;
25 
26     QWaitCondition *condition;
27     QMutex *mutex;
28     QSemaphore *semaphore;
29     int index;
30 
31 private:
32     int nProgress = 0;
33     QRandomGenerator *generator = QRandomGenerator::global();
34 
35 };
36 
37 #endif // THREADTEST1_H
threadtest1.h
 1 #include "threadtest1.h"
 2 
 3 ThreadTest1::ThreadTest1(int _index, QWaitCondition *_condition, QMutex *_mutex, QSemaphore *_semaphore, QObject *parent)
 4     : QThread(parent)
 5     , index(_index)
 6     , condition(_condition)
 7     , mutex(_mutex)
 8     , semaphore(_semaphore)
 9 {
10     qDebug() << __FUNCTION__ << " : " << index;
11 }
12 
13 ThreadTest1::~ThreadTest1()
14 {
15     qDebug() << __FUNCTION__ << " : " << index;
16 }
17 
18 void ThreadTest1::doSomething()
19 {
20     mutex->lock();
21     qDebug() << index << " :enter wait block";
22     semaphore->release(1);
23     condition->wait(mutex);
24     mutex->unlock();
25     qDebug() << index << " :start ";
26     nProgress = 0;
27     for( ; ; )
28     {
29         msleep(1000);
30         nProgress += generator->bounded(1, 20);
31         if(nProgress >= 100)
32         {
33             nProgress = 100;
34             emit updateProgress(nProgress);
35             break;
36         }
37         else{
38             emit updateProgress(nProgress);
39         }
40     }
41     qDebug() << index << " : finished!";
42 
43 }
44 
45 void ThreadTest1::run()
46 {
47     doSomething();
48 }
threadtest1.cpp
 1 #ifndef WIDGET_H
 2 #define WIDGET_H
 3 
 4 #include <QWidget>
 5 #include "threadtest1.h"
 6 #include <QProgressBar>
 7 #include <QVBoxLayout>
 8 #include <QVector>
 9 #include <QPushButton>
10 #include <QWaitCondition>
11 #include <QMutex>
12 #include <QThread>
13 #include <QSemaphore>
14 
15 QT_BEGIN_NAMESPACE
16 namespace Ui { class Widget; }
17 QT_END_NAMESPACE
18 
19 class Widget : public QWidget
20 {
21     Q_OBJECT
22 
23 public:
24     Widget(QWidget *parent = nullptr);
25     ~Widget();
26 
27 private slots:
28     void slotPushButton();
29 
30 public:
31     Ui::Widget *ui;
32     QWaitCondition condition;
33     QMutex mutex;
34     QSemaphore semaphore;
35 
36 public:
37     QVector<ThreadTest1*> vecThread;
38     QVector<QProgressBar*> vecProgressBar;
39     QVBoxLayout* layout;
40     QPushButton *btn;
41     const int cnt = 10;
42     void init();
43     void reset();
44 
45 
46 };
47 #endif // WIDGET_H
widget.h
 1 #include "widget.h"
 2 #include "ui_widget.h"
 3 
 4 struct ThreadClass : public QThread
 5 {
 6     Widget *widget;
 7     void run() override
 8     {
 9         widget->reset();
10         ThreadTest1 *thread;
11         for(int i = 0; i < widget->cnt; i++)
12         {
13             thread = new ThreadTest1(i, &widget->condition, &widget->mutex, &widget->semaphore);
14             widget->vecThread.push_back(thread);
15             connect(widget->vecThread.at(i), &ThreadTest1::updateProgress, widget->vecProgressBar.at(i), &QProgressBar::setValue);
16             connect(widget->vecThread.at(i), &ThreadTest1::finished, this, [=](){
17                 thread->deleteLater();
18                 widget->vecThread[i] = nullptr;
19             });
20             widget->vecThread.at(i)->start();
21         }
22         widget->semaphore.acquire(widget->cnt);
23         qDebug() << "all ready";
24         widget->condition.wakeAll();
25     }
26 
27     ThreadClass(Widget *_widget)
28         : widget(_widget)
29     {
30         qDebug() << __FUNCTION__;
31     }
32 
33     ~ThreadClass()
34     {
35         qDebug() << __FUNCTION__;
36     }
37 };
38 
39 Widget::Widget(QWidget *parent)
40     : QWidget(parent)
41     , ui(new Ui::Widget)
42 {
43     ui->setupUi(this);
44     init();
45 }
46 
47 Widget::~Widget()
48 {
49     delete ui;
50 }
51 
52 void Widget::slotPushButton()
53 {
54     ThreadClass *thread = new ThreadClass(this);
55     connect(thread, &ThreadClass::finished, thread, &QObject::deleteLater);
56     thread->start();
57     qDebug() << "Leave " << __FUNCTION__;
58 }
59 
60 
61 void Widget::init()
62 {
63     QProgressBar *bar;
64     layout = new QVBoxLayout(this);
65     for(int i = 0; i < cnt; i++)
66     {
67         bar = new QProgressBar(this);
68         bar->setRange(0, 100);
69         bar->reset();
70         vecProgressBar.push_back(bar);
71         layout->addWidget(bar);
72     }
73     btn = new QPushButton("Start", this);
74     connect(btn, &QPushButton::clicked, this, &Widget::slotPushButton);
75     layout->addWidget(btn);
76 }
77 
78 void Widget::reset()
79 {
80     for(int i = 0; i < cnt; i++)
81     {
82         vecProgressBar[i]->reset();
83     }
84     vecThread.clear();
85 }
widget.cpp
原文地址:https://www.cnblogs.com/endenvor/p/14075368.html