Qt5继承QObject多线程

qt4实现多线程主要是通过继承QThread,重写run来实现,但目前qt5由于继承qobject的多线程实现方式更加灵活,便捷,qt官方也推荐使用此方法来实现多线程。

实现思路:

定义MyThread类,定义一个start槽函数和back返回信号,同时在MainWindow声明thread_m信号。
#define MYTHREAD_H

#include <QThread>

class MyThread : public QObject
{
    Q_OBJECT
public:
    MyThread();
public slots:
    void start();
signals:
    void back();
};
#endif // MYTHREAD_H

new出MyThread为t1(创建自定义线程),将MainWindow的thread_m信号和t1的start槽函数绑定,
t1 = new MyThread();
t2 = new QThread();
t1->moveToThread(t2);
connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::print_static);
connect(this,&MainWindow::thread_m,t1,&MyThread::start);

将自定义线程移入子线程(通过movetothread实现)
t1->moveToThread(t2);

手动发出thread_m信号进入子线程
t2->start();//很重要,启动子线程,否则无法进入start槽函数
emit thread_m();

start槽函数里发射出back信号,(进入子线程处理)
void MyThread::start() {
   qDebug() << QThread::currentThreadId();
   emit back();
}

主界面接收back信号,并绑定到处理信号的函数上,及要处理的代码(同样在子线程中)。
connect(t1,&MyThread::back,[=](){
    while(true){
       qDebug() << QThread::currentThreadId();
       QThread::sleep(2);
    }
});

以上或许很多人会尝试直接调用start函数,但是这并不会进入子线程。要进入子线程必须要通过信号进入。

完整代码

mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>

class MyThread : public QObject
{
    Q_OBJECT
public:
    MyThread();
public slots:
    void start();
signals:
    void back();
};
#endif // MYTHREAD_H

mythread.cpp

#include "mythread.h"
#include <QDebug>
MyThread::MyThread(){
}

void MyThread::start() {
   qDebug() << QThread::currentThreadId();
   emit back();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "mythread.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
signals:
    void thread_m();
private slots:
    void print_static();
private:
    MyThread *t1;
    QThread *t2;
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include "mylabel.h"
#include <qthread.h>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    t1 = new MyThread();
    t2 = new QThread();
    t1->moveToThread(t2);
    connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::print_static);
    connect(this,&MainWindow::thread_m,t1,&MyThread::start);
    connect(t1,&MyThread::back,[=](){
        while(true){
            qDebug() << QThread::currentThreadId();
            QThread::sleep(2);
        }
    });

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::print_static(){
    t2->start();
    emit thread_m();
}

最后,这样仅仅实现了把代码移到子线程中执行,但是并没有自己能自定的暂停函数,以及清理子线程资源的代码,本人Qt小白,如果我讲述的内容有不足之处还请评论指出。