文章目录
目录
前言
介绍多线程的两种创建方法以及快速停止线程的方法
一、多线程的两种创建方法
1.继承QThread
1.自定义一个类,继承于QThread。
class MyThread:public QThread{
public:
virtual void run() override; //虚函数 线程处理函数(和主线程不在同一个线程)
signals:
void Finshed(); //信号 线程执行完发送
}
void MyThread::run() {
// 实现 -- 复杂的处理过程
emit Finished; // 发送线程
};
2.定义线程
MyThread mythread;
//MyThread* mythread = new MyThread();
3.开启线程
mythread.start();
//mythread->start();
通过执行mythread.start()或者mythread->start()启动run()函数,而不是直接调用run()函数。
4.自定义线程结束槽函数
run()函数结束前会发送 Finished信号,可以自定义槽函数打印线程结束;
public slots:
void SlotFinished();
——————————————————————
void MyWidget::SlotFinished(){
// 线程结束后的操作
qDebug() << "子线程结束!";
}
5.绑定线程结束信号和线程结束槽
connect(&mythread,&MyThread::Finished,this,&MyWidget::SlotFinished);
//connect(mythread,&MyThread::Finished,this,&MyWidget::SlotFinished);
【提示】MyThread类可以自定义多种方法,在run()函数内执行。
class MyThread:public QThread{
public:
virtual void run() override; //虚函数 线程处理函数(和主线程不在同一个线程)
void Func1();//方法1
void Func2();//方法2
signals:
void Finshed(); //信号 线程执行完发送
}
void MyThread::run() {
// 实现 -- 复杂的处理过程
Func1();
Func2();
emit Finished; // 发送线程
};
2.moveToThread方法
1.自定义一个功能实现类。
#ifndef THREAD_H
#define THREAD_H
#include <QObject>
class MyThread :public QObject
{
Q_OBJECT
public:
MyThread();
~Mythread();
void Func1();
void Func2();
};
#endif // THREAD_H
2.mythread.cpp中去完善构造函数与功能函数的具体实现。
#include "mythread.h"
#include <QDebug>
Thread::Thread()
{
}
void MyThread::Func1()
{
qDebug()<<"方法1";
}
void MyThread::Func2()
{
qDebug()<<"方法2";
}
3. 在你的窗口mywidget.h中添加各种头文件,创建两个信号,声明一个线程和刚刚创建的自定义功能实现类,添加两个按钮,声明两个响应按钮的槽函数。
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
#include <QThread>
#include <QObject>
#include "thread.h"
#include <QtWidgets/QPushButton>
namespace Ui {
class MyWidget ;
}
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget (QWidget *parent = 0);
~MyWidget ();
public slots:
void SlotDoFunc1();
void SlotDoFunc2();
signals:
void RunFunc1(); // 信号
void RunFunc2();
private:
Ui::MyWidget *ui;
QThread *Thread;//qt的线程类
MyThread *Mythread;//自定义的功能实现类
QPushButton* Func1QPushButton;//执行方法1按钮
QPushButton* Func2QPushButton;//执行方法2按钮
};
#endif // MYWIDGET_H
4.在mywidget.cpp中,先实例化Thread线程和Mythread,并且把Mythread这个类推向子线程,代码如下:
#include "mywidget.h"
#include "ui_mywidget.h"
MyWidget::MyWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MyWidget)
{
ui->setupUi(this);
Thread = new QThread;
Mythread = new MyThread;
connect(this,&MyWidget::RunFunc1,Mythread ,&Mythread::Func1);
connect(this,&MyWidget::RunFunc2,Mythread ,&Mythread::Func2);
Mythread->moveToThread(Thread);
connect(ui->Func1QPushButton, SIGNAL(clicked()), this, SLOT(SlotDoFunc1()));
connect(ui->Func2QPushButton, SIGNAL(clicked()), this, SLOT(SlotDoFunc2()));
}
void MyWidget::SlotDoFunc1()
{
//线程开启之前需要等之前的线程结束
if (Thread->isRunning())
{
wait();
}
emit RunFunc1();
Thread->start();
}
void MyWidget::SlotDoFunc2()
{
//线程开启之前需要等之前的线程结束
if (Thread->isRunning())
{
wait();
}
emit RunFunc2();
Thread->start();
}
MyWidget::~MyWidget()
{
delete ui;
}
二、多线程快速停止
1.线程停止介绍
子线程停止标志是run()函数运行结束,quit()、stop()【terminate()没试过,但是不建议使用,会出现内存问题】等并不会立刻停止run(),只是告诉线程要停止,真正停止还是需要等run()函数执行完毕。想快速停止必须要自定义方法,给出停止标志。以第一种创建多线程方法为例,具体操作如下:
2.具体实现
1.在线程类中,声明一个bool值的停止标志,以及停止函数。
class MyThread:public QThread{
Q_OBJECT
public:
MyThread();
~MyThread();
public:
virtual void run() override; //虚函数 线程处理函数(和主线程不在同一个线程)
public:
void Stop();//停止函数
signals:
void Finshed(); //信号 线程执行完发送
}
private:
bool m_bStop;//停止标志
2.在mythread.cpp的构造函数中初始化m_bStop为false,Stop方法中用来设置m_bStop的值。
MyThread::MyThread()
: QThread()
{
m_bStop = false;
}
void MyThread::Stop()
{
m_bStop = true;
}
3. 在run()函数的耗时的循环中加判断,退出循环。
void MyThread::run()
{
//m_bStop = false;//如果线程未被delete且多次停止启用需要
加这句保证循环开始时m_bStop始终为false,否则第二次开启将不会进入循环。
for(int i, i< 10000, i++)
{
if(m_bStop)
{
return;
}
//复杂的计算
}
emit Finished; // 发送线程
}
4.在需要停止线程的地方,调用线程类的Stop()方法即可。
void MyWidget::Func()
{
MyThread myThread;
myThread.Stop();
// MyThread* myThread = new MyThread();
// myThread->Stop();
}
如果在run()函数中调用线程类本身自定义的方法,方法中有耗时的循环,可类推。代码如下:
class MyThread:public QThread{
public:
virtual void run() override; //虚函数 线程处理函数(和主线程不在同一个线程)
void Func();//线程类本身自定义方法
signals:
void Finshed(); //信号 线程执行完发送
}
void MyThread::run() {
m_bStop = false;
Func();//实现线程类本身自定义方法
emit Finished; // 发送线程
};
void MyThread::Func() {
for(int i, i< 10000, i++)
{
if(m_bStop)
{
return;
}
//复杂的计算
}
};
总结
正在学习中,欢迎批评指正!