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();

}             

 

 

 


posted on 2021-03-03 16:26  大王背我来巡山®  阅读(52)  评论(0)    收藏  举报