QT中多线程的使用(一)
参考资料
https://subingwen.cn/qt/thread/#1-%E7%BA%BF%E7%A8%8B%E7%B1%BB-QThread
https://www.bilibili.com/video/BV1iN411f7dY?buvid=XU932919AEC08339E30CE57D39A2BABF6A44F&from_spmid=search.search-result.0.0&is_story_h5=false&mid=rSmqqQLB5PQj7nof4wjfpQ%3D%3D&plat_id=114&share_from=ugc&share_medium=android&share_plat=android&share_session_id=a01714b7-a97c-4ec7-8dbb-548099f05c05&share_source=WEIXIN&share_source=weixin&share_tag=s_i&spmid=united.player-video-detail.0.0×tamp=1737024828&unique_k=gr9tHaA&up_id=147020887&vd_source=b3723521e243814388688d813c9d475f&spm_id_from=333.788.player.switch&p=7
1.使用方式
在Qt中使用多线程来处理比较复杂的逻辑时,可以将这个逻辑写到一个类中。这个类继承QThread类,并且重写其中的run()方法,当调用start()方法的时候,run()方法会被自动调用。
假设现在要生成10000个随机数,如果在主线程中直接生成,那么主界面会非常的卡顿,此时需要重新创建一个子线程。
#pragma once
#include <QThread>
class Generate:public QThread
{
Q_OBJECT
public:
explicit Generate(QObject* parent = nullptr);
void recvNum(int num);
void setNum(int num);
protected:
//重写QThread类中的run方法
void run()override;
signals:
void sendArray(QVector<int> num);
private:
int m_num;
};
#include "Generate.h"
#include <QDebug>
#include <QVector>
#include <QElapsedTimer>
#include <QRandomGenerator>
Generate::Generate(QObject* parent)
: QThread{ parent }
{}
void Generate::recvNum(int num)
{
m_num = num;
}
void Generate::setNum(int num)
{
m_num = num;
}
void Generate::run()
{
//生成m_num个随机数
qDebug() << "生成随机数的线程的线程地址是:" << QThread::currentThread();
QVector<int> list;
//list.resize(m_num);
//统计生成这些随机数所消耗的时间
QElapsedTimer time;
time.start();
for (int i = 0; i < m_num; i++)
{
list.push_back(QRandomGenerator::global()->bounded(10000));
}
int milsec = time.elapsed();
qDebug() << "生成" << m_num << "个随机数总共耗时" << QString::number(milsec);
//生成完随即数后发送信号告诉主线程可以使用这些数据了
emit sendArray(list);
}
当主线程需要使用的时候,可以通过run()方法来调用这个类的处理逻辑。在主线程中的使用方式如下:
2.例子:使用多线程实现对10000个数据的排序,并通过冒泡排序和快速排序分别对二者进行排序,得到的结果显示在界面上。
主界面代码:
#pragma once
#include <QPushButton>
#include <QWidget>
#include <QListWidget>
#include <QVBoxLayout>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QWidget>
#include <QMainWindow>
//创建程序所需要的界面
class Ui_QThread1Page {
public:
//界面所需要的组件
QGroupBox* groupBox;
QGroupBox* groupBox_2;
QGroupBox* groupBox_3;
QListWidget* randList;
QListWidget* bubbleList;
QListWidget* quickList;
QHBoxLayout* hboxLayout4;
QPushButton* btnStart;
QVBoxLayout* vboxLayout;
QVBoxLayout* vboxLayout1;
QVBoxLayout* vboxLayout2;
QVBoxLayout* vboxLayout3;
public:
void setupUi(QWidget* parent)
{
groupBox = new QGroupBox;
groupBox_2 = new QGroupBox;
groupBox_3 = new QGroupBox;
groupBox->setTitle("randList");
groupBox_2->setTitle("bubbleList");
groupBox_3->setTitle("quickList");
randList = new QListWidget;
bubbleList = new QListWidget;
quickList = new QListWidget;
hboxLayout4 = new QHBoxLayout;
btnStart = new QPushButton;
btnStart->setText("btnStart");
vboxLayout = new QVBoxLayout;
vboxLayout1 = new QVBoxLayout;
vboxLayout2 = new QVBoxLayout;
vboxLayout3 = new QVBoxLayout;
vboxLayout1->addWidget(randList);
groupBox->setLayout(vboxLayout1);
vboxLayout2->addWidget(bubbleList);
groupBox_2->setLayout(vboxLayout2);
vboxLayout3->addWidget(quickList);
groupBox_3->setLayout(vboxLayout3);
hboxLayout4->addWidget(groupBox);
hboxLayout4->addWidget(groupBox_2);
hboxLayout4->addWidget(groupBox_3);
vboxLayout->addLayout(hboxLayout4);
vboxLayout->addWidget(btnStart);
parent->setLayout(vboxLayout);
parent->setFixedSize(800,600);
}
};
namespace Ui {
class QThread1Page :public Ui_QThread1Page {};
}
#pragma once
#include <QtWidgets/QWidget>
#include <QMainWindow>
#include "ui_QThread1.h"
class QThread1 : public QWidget
{
Q_OBJECT
public:
QThread1(QWidget *parent = nullptr);
~QThread1();
signals:
void starting(int num);
private:
Ui::QThread1Page *ui_;
};
#include "QThread1.h"
#include "Generate.h"
#include "BubbleSort.h"
#include "QuickSort.h"
#include <QString>
#include <QDebug>
QThread1::QThread1(QWidget *parent)
: QWidget(parent)
, ui_(new Ui::QThread1Page)
{
//1.初始化显示界面
ui_->setupUi(this);
//2.创建对应的子线程类
Generate* gen = new Generate;//生成随机数
BubbleSort* bubble = new BubbleSort;//冒泡排序
QuickSort* quick = new QuickSort;//快速排序
/*
* 因为上述的三个子类都继承了QThread类,并且重写了run()方法
* 所以调用对应对象的btnStart方法时,run中的函数会在子线程中运行
*/
//3.主线程的逻辑
//connect(this, &QThread1::starting, gen, &Generate::recvNum);
connect(ui_->btnStart, &QPushButton::clicked, this, [=]()
{
gen->setNum(1000000);
//emit starting(100000);
gen->start();
});
//两个子线程接收数据
connect(gen, &Generate::sendArray, bubble, & BubbleSort::recvArray);
connect(gen, &Generate::sendArray, quick, &QuickSort::recvArray);
//主线程开始显示数据,并且启动子线程的排序功能
connect(gen, &Generate::sendArray, this, [=](QVector<int> list)->void
{
for (int i = 0; i < list.size(); i++)
{
ui_->randList->addItem(QString::number(list.at(i)));
}
});
connect(gen, &Generate::sendArray, this, [=](QVector<int> list)->void
{
bubble->start();
quick->start();
});
//当子线程排序完数据后,在主线程中显示数据
connect(bubble, &BubbleSort::finish, this, [=](QVector<int>list)
{
for (int i = 0; i < list.size(); i++)
{
ui_->bubbleList->addItem(QString::number(list.at(i)));
}
});
connect(quick, &QuickSort::finish, this, [=](QVector<int>list)
{
for (int i = 0; i < list.size(); i++)
{
ui_->quickList->addItem(QString::number(list.at(i)));
}
});
connect(this, &QThread1::close, this, [=]()
{
gen->quit();
gen->wait();
gen->deleteLater();//相当于delete gen
bubble->quit();
bubble->wait();
bubble->deleteLater();//相当于delete bubble
quick->quit();
quick->wait();
quick->deleteLater();//相当于delete quick
qDebug() << "process quit...";
});
}
QThread1::~QThread1()
{}
#pragma once
#include <QThread>
#include <QVector>
class BubbleSort : public QThread
{
Q_OBJECT
public:
explicit BubbleSort(QObject* parent = nullptr);
void recvArray(QVector<int> list);
protected:
virtual void run()override;
signals:
void finish(QVector<int> list);
private:
QVector<int> m_list;
};
#include "BubbleSort.h"
#include <QDebug>
#include <QElapsedTimer>
BubbleSort::BubbleSort(QObject* parent)
: QThread(parent)
{
}
void BubbleSort::recvArray(QVector<int> list)
{
m_list = list;
}
void BubbleSort::run()
{
qDebug() << "bubble sort thread address is:" << QThread::currentThread();
QElapsedTimer time;
time.start();
int temp;
for (int i = 0; i < m_list.size(); ++i)
{
for (int j = 0; j < m_list.size() - i - 1; ++j)
{
if (m_list[j] > m_list[j + 1])
{
temp = m_list[j];
m_list[j] = m_list[j + 1];
m_list[j + 1] = temp;
}
}
}
int milsec = time.elapsed();
qDebug() << "bubble sort time is " << milsec << "ms";
emit finish(m_list);
}
#pragma once
#include <QThread>
#include <QVector>
class QuickSort : public QThread
{
Q_OBJECT
public:
explicit QuickSort(QObject* parent = nullptr);
void recvArray(QVector<int> list);
private:
void quickSort(QVector<int>& list, int l, int r);
protected:
virtual void run()override;
signals:
void finish(QVector<int> list);
private:
QVector<int> m_list;
};
#include "QuickSort.h"
#include <QDebug>
#include <QElapsedTimer>
QuickSort::QuickSort(QObject* parent)
: QThread(parent)
{
}
void QuickSort::recvArray(QVector<int> list)
{
m_list = list;
}
void QuickSort::run()
{
qDebug() << "quick sort thread address is :" << QThread::currentThread();
QElapsedTimer time;
time.start();
quickSort(m_list, 0, m_list.size() - 1);
int milsec = time.elapsed();
qDebug() << "quick sort time is" << milsec << "ms";
emit finish(m_list);
}
void QuickSort::quickSort(QVector<int>& s, int l, int r)
{
if (l < r)
{
int i = l, j = r;
int x = s[l];
while (i < j)
{
while (i < j && s[j] >= x)
{
j--;
}
if (i < j)
{
s[i++] = s[j];
}
while (i < j && s[i] < x)
{
i++;
}
if (i < j)
{
s[j--] = s[i];
}
}
s[i] = x;
quickSort(s, l, i - 1);
quickSort(s, i + 1, r);
}
}
#include "QThread1.h"
#include <QtWidgets/QApplication>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qRegisterMetaType<QVector<int>>("QVector<int>");
QThread1 w;
w.show();
return a.exec();
}
原文地址:https://blog.csdn.net/weixin_40933496/article/details/145229434
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!