上一篇举例使用了QT的多线程使用方式一
下面举例使用第二种方式,参考链接可看上一篇
QThread使用方式二
同样的,程序需要实现如下功能:
除了主线程外,创建随机数生成、冒泡排序、快速排序三个子线程,并将计算结果分别显示,可以得到每个线程花费时间,如下。
main.cpp
#include "QtThread.h"
#include <QtWidgets/QApplication>
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
//需要注册的原因可参考https://blog.csdn.net/wadfji/article/details/54406767
//传递QVector<int>时需要注册
qRegisterMetaType<QVector<int>>("QVector<int>");
QtThread w;
w.show();
return a.exec();
}
QtThread.h创建工程时起的类名
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_QtThread.h"
class QtThread : public QMainWindow
{
Q_OBJECT
public:
QtThread(QWidget* parent = Q_NULLPTR);
signals:
void starting(int num);
private:
Ui::QtThreadClass ui;
};
QtThread.cpp
#include "QtThread.h"
#include "mythread.h"
#include <qthread.h>
QtThread::QtThread(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//1.创建子线程对象
QThread* t1 = new QThread;
QThread* t2 = new QThread;
QThread* t3 = new QThread;
//2.创建任务类对象
//创建生成随机数的子线程对象
Generate* gen = new Generate;
//创建排序类的对象
BubbleSort* bubble = new BubbleSort;
QuickSort* quick = new QuickSort;
//3.将任务对象移动到某个子线程中
gen->moveToThread(t1);
bubble->moveToThread(t2);
quick->moveToThread(t3);
//主线程发送需要的随机数个数给生成随机数的子线程
connect(this, &QtThread::starting, gen, &Generate::working);
//点击按钮启动子线程,生成随机数子线程开始运行
connect(ui.btn_start, &QPushButton::clicked, this, [=]() {
emit starting(10000);
t1->start();
});
//生成随机数的子线程把数据发送给排序的两个子线程和主线程
connect(gen, &Generate::sendArray, bubble, &BubbleSort::working); //排序线程接收数据
connect(gen, &Generate::sendArray, quick, &QuickSort::working);
connect(gen, &Generate::sendArray, this, [=](QVector<int> list) {
//排序线程开始运行
t2->start();
t3->start();
//显示随机生成的数
for (int i = 0; i < list.size(); i++)
{
ui.randList->addItem(QString::number(list.at(i)));
}
});
//主线程接收排序后的结果
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)));
}
});
//内存回收,当前窗口关闭的时候会发送destroyed信号
connect(this, &QtThread::destroyed, this, [=]() {
t1->quit(); t1->wait(); t1->deleteLater();
t2->quit(); t2->wait(); t2->deleteLater();
t3->quit(); t3->wait(); t3->deleteLater();
gen->deleteLater();
bubble->deleteLater();
bubble->deleteLater();
});
}
mythread.h包含三个任务类对象
#pragma once
#include <QObject>
#include <qvector.h>
class Generate : public QObject
{
Q_OBJECT
public:
explicit Generate(QObject* parent = nullptr);
~Generate();
//任务函数
void working(int num);
signals:
void sendArray(QVector<int> num);
};
//*****************冒泡排序*********************
class BubbleSort : public QObject
{
Q_OBJECT
public:
explicit BubbleSort(QObject* parent = nullptr);
~BubbleSort();
void working(QVector<int> list);
signals:
void finish(QVector<int> list);
};
//********************快速排序*************************
class QuickSort : public QObject
{
Q_OBJECT
public:
explicit QuickSort(QObject* parent = nullptr);
~QuickSort();
void working(QVector<int> list);
private:
void quickSort(QVector<int>& list, int l, int r);
signals:
void finish(QVector<int> list);
};
mythread.cpp
#include "mythread.h"
#include <qelapsedtimer.h>
#include <qdebug.h>
#include <qthread.h>
//*******************生成随机数******************
Generate::Generate(QObject* parent)
: QObject(parent)
{
}
Generate::~Generate()
{
}
void Generate::working(int num)
{
qDebug() << "生成随机数的线程的线程地址:" << QThread::currentThread();
QVector<int> list;
QElapsedTimer time;
time.start();
for (int i = 0; i < num; i++)
{
list.push_back(qrand() % 100000);
}
int milsec = time.elapsed();
qDebug() << "生成" << num << "个随机数总共用时:" << milsec << "毫秒";
emit sendArray(list); //发送信号给主线程
}
//*****************冒泡排序**********************
BubbleSort::BubbleSort(QObject* parent) :QObject(parent)
{
}
BubbleSort::~BubbleSort()
{
}
void BubbleSort::working(QVector<int> list)
{
qDebug() << "冒泡排序的线程地址:" << QThread::currentThread();
QElapsedTimer time;
time.start();
for (int i = 0; i < list.size(); i++)
{
for (int j = 0; j < list.size() - i - 1; j++)
{
if (list[j] > list[j + 1])
{
int temp = list[j];
list[j] = list[j + 1];
list[j + 1] = temp;
}
}
}
int milsec = time.elapsed();
qDebug() << "冒泡排序总共用时:" << milsec << "毫秒";
emit finish(list); //发送信号给主线程
}
//********************快速排序**************************
QuickSort::QuickSort(QObject* parent) :QObject(parent)
{
}
QuickSort::~QuickSort()
{
}
//快速排序
void QuickSort::quickSort(QVector<int>& s, int l, int r)
{
if (l < r)
{
int i = l, j = r;
//拿出第一个元素保存到x中,第一个位置成为一个坑
int x = s[l];
while (i < j)
{
//从右向左找小于x的数
while (i < j && s[j] >= x)
{
//左移,直到遇到小于等于x的数
j--;
}
if (i < j)
{
//将右侧找到的小于x的元素放入左侧坑中,右侧出现一个坑
//左侧元素索引后移
s[i++] = s[j];
}
//从左向右找大于等于x的数
while (i < j && s[i] < x)
{
//右移,直到遇到大于x的数
i++;
}
if (i < j)
{
//将左侧找到的元素放入右侧坑中,左侧出现一个坑
//右侧元素索引向前移动
s[j--] = s[i];
}
}
//此时,i=j,将保存在x中的数填入坑中
s[i] = x;
quickSort(s, l, i - 1);
quickSort(s, i + 1, r);
}
}
void QuickSort::working(QVector<int> list)
{
qDebug() << "快速排序的线程地址:" << QThread::currentThread();
QElapsedTimer time;
time.start();
quickSort(list, 0, list.size() - 1);
int milsec = time.elapsed();
qDebug() << "快速排序总共用时:" << milsec << "毫秒";
emit finish(list); //发送排序完的数据给主线程
}












网友评论