文章目录
- 1. 概述
- 2. UML 类的关系图
- 3. 代码:
- 4. 运行结果及说明
- 5. 结语
1. 概述
任何继承于QThread的线程都是通过继承 QThread 的run函数来实现多线程的,因此,必须重写QThread的run函数,把复杂逻辑写在QThread的run函数中。然后在主线程中调用 start() 函数来启动子线程。
2. UML 类的关系图
3. 代码:
首先写 MyThread 类,该类继承于 QThread 类,该类中自定义了信号和槽,并且重写了 run 函数,头文件如下:
//
// MyThread.h
//
#ifndef DEL2_MYTHREAD_H
#define DEL2_MYTHREAD_H#include <QThread>
#include <QDebug>class MyThread : public QThread
{
Q_OBJECTpublic:explicit MyThread(QObject* parent = nullptr);signals:void myThreadSignal(const int); // 自定义发送的信号public slots:static void myThreadSlot(int); // 自定义槽函数protected:void run() override ;
};#endif //DEL2_MYTHREAD_H//
// mythread.cpp
//
#include "mythread.h"MyThread::MyThread(QObject* parent): QThread(parent)
{
}//2. 新线程中的 0x4684
void MyThread::run()
{qDebug() << __FUNCTION__ << " Thread ID: " << QThread::currentThreadId() << "\n";emit myThreadSignal(100); // 发送结束信号exec();
}//3. 主线程中的 0x5120
void MyThread::myThreadSlot(const int val)
{qDebug() << __FUNCTION__ << " Thread ID: " << QThread::currentThreadId() << ", val: " << val <<"\n";
}
在 ThreadController 类中实现 MyThread 的调用
//
// threadcontroller.h
//
#ifndef THREADCONTROLLER_H
#define THREADCONTROLLER_H#include <QObject>
#include "mythread.h"class ThreadController : public QObject
{
Q_OBJECTpublic:explicit ThreadController(QObject *parent = nullptr);~ThreadController() override ;public slots:static void handleResults(int result); // 处理子线程执行的结果signals:void operate(const int); // 发送信号,触发线程private:MyThread* _myThread ;};#endif // THREADCONTROLLER_H//
// WorkerController.cpp
//
#include "threadcontroller.h"ThreadController::ThreadController(QObject *parent) : QObject(parent)
{_myThread = new MyThread ;connect(_myThread, &MyThread::myThreadSignal, this, &ThreadController::handleResults);// 该线程结束时销毁connect(_myThread, &QThread::finished, this, &QObject::deleteLater);connect(this, &ThreadController::operate, _myThread, &MyThread::myThreadSlot);// 启动该线程_myThread->start();// 当前线程挂起 3sQThread::sleep(3);//3. --- 先执行当前槽函数,再执行run中槽函数emit operate(99);
}ThreadController::~ThreadController()
{_myThread->quit();_myThread->wait();
}//4. 主线程中的 0x5120
void ThreadController::handleResults(const int result)
{qDebug() << __FUNCTION__ << " Thread ID:" << QThread::currentThreadId() << ", last result: " << result;
}
接下来就是 main 函数,主函数中我们新建一个 Controller 对象,开始执行:
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include "threadcontroller.h"int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug() << __FUNCTION__ << " Thread ID:" << QThread::currentThreadId() << '\n' ;ThreadController c ;return a.exec(); // 进入事件循环
}
4. 运行结果及说明
注意:
- 只有 run() 中的才是新线程,其余都是主线程!
- QThread::sleep(3); 使用后,当前主线程挂起 3 秒,而子线程中 run() 继续执行,休眠结束后才会运行主线程的槽函数!
5. 结语
子类化 QThread 的方法,就是重写了 QThread 中的 run() 函数,在 run() 函数中定义需要的工作。这样的结果是,我们自定义的子线程调用 start() 函数后,便开始执行 run() 函数。如果在自定义的线程类 MyThread 中定义相关的槽函数,那么这些槽函数不会由子类化的QThread 自身事件循环所执行,而是由该子线程的拥有者(一般都是主线程)来执行。
而 qt 的线程设计不是希望通过继承去实现多线程,而是希望线程也是作为一个对象可以直接使用,也就是 QObject的moveToThread方法
本文也只是初步的学习,没有关注于线程的释放和创建,进一步使用可以参考: Qt使用多线程的一些心得
参考: QT 中的多线程—继承 QThread 篇