QT 中的多线程之继承 Thread

news/2024/11/29 7:37:12/

文章目录

  • 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. 运行结果及说明

在这里插入图片描述

 
在这里插入图片描述

注意:

  1. 只有 run() 中的才是新线程,其余都是主线程!
  2. QThread::sleep(3); 使用后,当前主线程挂起 3 秒,而子线程中 run() 继续执行,休眠结束后才会运行主线程的槽函数!

5. 结语

子类化 QThread 的方法,就是重写了 QThread 中的 run() 函数,在 run() 函数中定义需要的工作。这样的结果是,我们自定义的子线程调用 start() 函数后,便开始执行 run() 函数。如果在自定义的线程类 MyThread 中定义相关的槽函数,那么这些槽函数不会由子类化的QThread 自身事件循环所执行,而是由该子线程的拥有者(一般都是主线程)来执行。

而 qt 的线程设计不是希望通过继承去实现多线程,而是希望线程也是作为一个对象可以直接使用,也就是 QObject的moveToThread方法

本文也只是初步的学习,没有关注于线程的释放和创建,进一步使用可以参考: Qt使用多线程的一些心得

参考: QT 中的多线程—继承 QThread 篇


http://www.ppmy.cn/news/58482.html

相关文章

常见的10个SQL语句性能优化策略

SQL语句性能优化策略 1. 为 WHERE 及 ORDER BY 涉及的列上建立索引 对查询进行优化&#xff0c;应尽量避免全表扫描&#xff0c;首先应考虑在 WHERE 及 ORDER BY 涉及的列上建立索引 2. where中使用默认值代替null 应尽量避免在 WHERE 子句中对字段进行 NULL 值判断&#xff0…

【网站架构】Nginx 4层、7层代理配置,正向代理、反向代理详解

大家好&#xff0c;欢迎来到停止重构的频道。 本期我们讨论网络代理。 在往期《大型网站 安全性》介绍过&#xff0c;出于网络安全的考虑&#xff0c;一般大型网站都需要做网络区域隔离&#xff0c;以防止攻击者直接操控服务器。 网站系统的应用及数据库都会放在这个网络安全…

轻松搭建自己的ChatGPT聊天机器人,让AI陪你聊天!

随着人工智能技术的发展&#xff0c;聊天机器人已经成为了我们生活中的一部分。无论是在客服机器人上还是智能助手上&#xff0c;聊天机器人都能够给我们带来真正的便利和快乐。现在&#xff0c;你也可以轻松搭建自己的ChatGPT聊天机器人&#xff0c;和它天马行空地聊天&#x…

java 多用户即时通信系统的实现 万字详解

目录 前言 一、拾枝杂谈 1.项目开发大体流程 : 2.多用户即时通信系统分析 : 1 需求分析 2 整体分析 二、用户登录 1.准备工作 : 2.客户端 : 1 菜单界面 2 登录验证 3 线程创建 4 线程管理 3.服务端 : 1 用户验证 2 线程创建 3 线程管理 4.登录测试 : 三、在线列表 1.…

对模式的迷信,大部分是幻觉和妄想

对模式的迷信&#xff0c;大部分是幻觉和妄想 往往有严重的投机心理 郑翔洲&#xff0c;所谓模式设计专家 还是有点虚&#xff0c;仅供一点参考 说苹果、说华为、说小米这些总结都是事后诸葛亮 趣讲大白话&#xff1a;商业模式被妖魔化 【趣讲信息科技153期】 ****************…

【网络】网络基础协议概念IPMAC地址

文章目录 网络基础网络的发展历程网络在哪里的问题网络协议栈各部分所处位置&#xff1a;网络协议栈各层的作用网络协议栈分层的目的 网络协议的概念 网络协议协议分层的好处理解各层之间直接通信OSI七层模型TCP/IP五层&#xff08;或四层&#xff09;模型 网络传输基本流程同局…

计算机视觉 | 人工智能 自己总结 (下)

目录 立体视觉立体视觉的概念视差信息的概念立体匹配目标检测和跟踪三维重建立体图像拼接 立体视觉 立体视觉的概念 立体视觉是指人类双眼所产生的深度感觉&#xff0c;也称为立体感或深度感。它是由于两只眼睛分别观察到同一物体的微小差异而产生的。 当两只眼睛看到同一物…

刷题刷题。

租用游艇 1.格式化输入二维数组&#xff1a;1-2&#xff0c;1-3&#xff0c;1-4&#xff0c;2-3&#xff0c;2-4&#xff0c;3-4... ... for(int i1; i<n-1; i) for(int ji1; j<n; j) 2.三重for循环枚举路径&#xff1a;第…