QT多线程的实现有多种方式
1. 通过继承QThread类,并重写线程函数虚函数run(),并调用start()方法启动线程
2. 通过基类QOBject类中的moveToThread来实现
3. C++11引入lambda表达是后,通过QtConcurrent类配合lambda表达式启动新的线程;
方式1. 通过继承QThread类,并重写线程函数虚函数run(),并调用start()方法启动线程
示例1
// 头文件
#include <QThread>
class MyThread : public QThread
{
Q_OBJECT
public:
MyThread(QObject* parent = nullptr);
~MyThread();
protected:
void run(); // 线程处理函数
};
// cpp文件
#include <mythread.h>
MyThread::MyThread(QObject* parent = nullptr) : QThread(parent)
{
}
MyThread::~MyThread()
{
}
// 线程处理函数
void run()
{
while(1)
{
qDebug()<<"Thread is running!";
}
}
// 主函数调用线程
#include <mythread.h>
#include <QApplication>
int main()
{
QApplication a(argc, argv);
MyThread thread; // 创建线程
thread.start(); // 启动线程
return a.exec();
}
方法2. 通过基类QOBject类中的moveToThread来实现
只要是继承自QObject类的其他类,都会有一个movetothread()方法,通过该方法将该类的实例化对象移入一个线程,启动线程后,通过信号-槽的方式启动线程处理函数,对象的槽函数就会在新的线程中处理,并且该对象的事件机制也在新的线程中执行。
示例2
// 头文件
#include <QObject>
class MyThread : public QObject
{
Q_OBJECT
public:
MyThread(QObject* parent = nullptr);
~MyThread();
protected slots:
void threadProcess(); // 线程处理函数
};
// cpp文件
#include <mythread.h>
MyThread::MyThread(QObject* parent = nullptr) : QObject(parent)
{
}
MyThread::~MyThread()
{
}
// 线程处理函数
void
MyThread::threadProcess() {
while(1) {
qDebug()<<"Thread is running!";
}
}
// 另有一个类,用于给给线程发送信号
#include <QObject>
class Signal: public QObject
{
Q_OBJECT
public:
Signal(QObject* parent = nullptr);
~Signal();
signals:
void startProcess(); // 启动信号
};
// 主函数调用线程
#include <mythread.h>
#include <QApplication>
#include <QThread>
int main()
{
QApplication a(argc, argv);
MyThread myThread; // 创建线程
Signal signal; // 创建信号类
connect(&signal, &Signal::startProcess, &myThread, &MyThread::threadProcess); // 绑定信号和槽
QThread thread; // 创建新线程
myThread.moveToThread(&thread); // 将线程类移入新线程
thread.start(); // 启动线程
emit signal.startProcess(); // 发送启动信号, 槽函数(线程处理函数)threadProcess就会在线程thread中执行,myThread对象的事件机制也在thread中进行。
return a.exec();
}
通常在使用此方法时,将线程封装在类中,这样,在使用该类时,无需再同时创建一个线程。
示例3
// 头文件
#include <QThread>
#include <QObject>
// 自定义类,继承自QObject
Class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject *parent = nullptr);
private:
QThread _thread;
};
// cpp文件
MyObject::MyObject(QObject *parent)
{
// 放入线程
this.moveToThread(&_thread);
// 启动线程
_thread.start();
}
注意:一般启动线程的过程不封装在构造函数中,因为这样的话,需要重新创建对象才能启动线程,有时候我们只想创建一次对象,但是在不同的时候反复启动线程,因此,将启动线程封装在一个专门的函数中,方便后续再次启动线程。
示例4
// 头文件
#include <QThread>
#include <QObject>
// 自定义类,继承自QObject
Class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject *parent = nullptr);
void startThread(); // 专门用于启动线程的函数
private:
QThread* _pthread; // 此处使用指针,在堆区开辟内存
};
// cpp文件
MyObject::MyObject(QObject *parent)
{
// 放入线程
this.moveToThread(&_thread);
}
// 启动线程的函数
MyObject::startThread()
{
// 启动线程
_thread.start();
}
方法3. 通过QtConcurrent类配合lambda表达是实现
// 主函数调用线程
#include <mythread.h>
#include <QtConcurrent>
#include <QThread>
#include <QDebug>
int main()
{
QApplication a(argc, argv);
QtConcurrent::run([](){ // 启动新线程
while(1)
{
qDebug()<<"New Thread is running!";
}
});
return a.exec();
}