QT多线程
前言
默认情况下,QT只存在一个主线程,而且跟窗口有关的操作放在主线程中。如果程序中有比较费时的操作需要处理,由于只有一个线程存在,当你试着拖拽界面的时候就会出现卡顿。为了处理复杂的操作,我们必须引入多线程。一、任务分工
主线程:QT中默认的线程,也叫窗口线程,负责窗口事件处理或者窗口控件数据的更新
子线程:负责后台的业务逻辑处理,子线程中不能对窗口对象做任何操作,这些事情需要交给主线程处理
主线程和子线程之间如果要进行数据的传递,必须使用Qt中的信号槽机制!
二、如何创造
Qt 中提供了一个线程类QThread,通过这个类就可以创建子线程了。
步骤如下:
1、创建一个子类,让其继承 QT 中的线程类 QThread
2、在子类中重写父类的 run () 方法,处理的具体的业务流程都要在run()方法中
3、在主线程中创建子线程对象
4、在主线程中调用 start () 方法启动子线程
三、关键步骤
///创建子线程Generate
class Generate : public QThread
{
Q_OBJECT
...
void run() override;
...
};
//重写run()方法
void Generate::run()
{
...
}
//在主线程中创建子线程对象
Generate *gen = new Generate;
//在主线程中调用start()方法启动子线程
gen->start();
四、代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void starting(int num);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include<QVector>
class Generate : public QThread
{
Q_OBJECT
public:
explicit Generate(QObject *parent = nullptr);
void recvNum(int num);
protected:
void run() override;
signals:
void sendArray(QVector<int> list);
void spendTime(int);
public slots:
private:
int m_num;
};
class BubbleSort : public QThread
{
Q_OBJECT
public:
explicit BubbleSort(QObject *parent = nullptr);
void recvArray(QVector<int>list);
protected:
void run() override;
signals:
void finish(QVector<int> num);
void spendTime(int);
public slots:
private:
QVector<int> m_list;
};
class QuickSort : public QThread
{
Q_OBJECT
public:
explicit QuickSort(QObject *parent = nullptr);
void recvArray(QVector<int> list);
private:
void quickSort(QVector<int> &list,int s,int e);
protected:
void run() override;
signals:
void finish(QVector<int> num);
void spendTime(int);
public slots:
private:
QVector<int> m_list;
};
#endif // MYTHREAD_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
qRegisterMetaType<QVector<int>>("QVector<int>");
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<mythread.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("线程_排序比较");
Generate *gen = new Generate;
QuickSort *quick = new QuickSort;
BubbleSort *bubble = new BubbleSort;
connect(this,&MainWindow::starting,gen,&Generate::recvNum);
connect(ui->start,&QPushButton::clicked,this,[=]()
{
gen->start();
emit starting(30000);
});
connect(gen,&Generate::sendArray,bubble,&BubbleSort::recvArray);
connect(gen,&Generate::sendArray,quick,&QuickSort::recvArray);
connect(gen,&Generate::sendArray,this,[=](QVector<int>list)
{
bubble->start();
quick->start();
for(int i = 0;i<list.size();i++)
{
//ui->randList->addItem(QString::number(list.at(i)));
ui->randList->addItem(QString::number(list.at(i)));
}
});
connect(gen,&Generate::spendTime,this,[=](int time)
{
ui->showSome->append("生成这些随机数花费了"+QString::number(time)+"毫秒");
});
connect(bubble,&BubbleSort::spendTime,this,[=](int time)
{
ui->showSome->append("冒泡排序花费了"+QString::number(time)+"毫秒");
});
connect(quick,&QuickSort::spendTime,this,[=](int time)
{
ui->showSome->append("快速排序花费了"+QString::number(time)+"毫秒");
});
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, &MainWindow::destroy, this, [=]()
{
gen->quit();
gen->wait();
gen->deleteLater(); // delete t1;
bubble->quit();
bubble->wait();
bubble->deleteLater();
quick->quit();
quick->wait();
quick->deleteLater();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
mythread.cpp
#include "mythread.h"
#include<QElapsedTimer>
#include <QDebug>
//#include<debug.h>
Generate::Generate(QObject *parent) : QThread(parent)
{
}
void Generate::recvNum(int num)
{
m_num = num;
}
void Generate::run()
{
qDebug()<<"生成随机数线程的地址:"<<QThread::currentThread();
QVector<int> List;
QElapsedTimer time;
time.start();
for(int i = 0;i < m_num;i++)
{
List.push_back(qrand() % 100000);
}
int millisec = time.elapsed();
//qDebug()<<"总共花费了"<<millisec<<"毫秒生成了"<<m_num<<"个随机数";
emit sendArray(List);
emit spendTime(millisec);
}
BubbleSort::BubbleSort(QObject *parent):QThread(parent)
{
}
void BubbleSort::recvArray(QVector<int> list)
{
m_list = list;
}
void BubbleSort::run()
{
qDebug()<<"冒泡排序线程的地址:"<<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 millisec = time.elapsed();
//qDebug()<<"冒泡排序总共花费了"<<millisec<<"毫秒";
emit finish(m_list);
emit spendTime(millisec);
}
QuickSort::QuickSort(QObject *parent): QThread(parent)
{
}
void QuickSort::recvArray(QVector<int> list)
{
m_list = list;
}
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::run()
{
qDebug()<<"快速排序线程的地址:"<<QThread::currentThread();
QElapsedTimer time;
time.start();
quickSort(m_list, 0, m_list.size()-1);
int millisec = time.elapsed();
//qDebug()<<"快速排序总共花费了"<<millisec<<"毫秒";
emit finish(m_list);
emit spendTime(millisec);
}
mainwindow.ui
参考链接:
https://subingwen.cn/qt/thread/.