QT 中的多线程之继承 Thread

news2024/11/21 0:18:05

文章目录

  • 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_OBJECT

public:
    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_OBJECT

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

    // 当前线程挂起 3s
    QThread::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.coloradmin.cn/o/483775.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

effective c++ item40-44

item40:谨慎的使用多重继承 多重继承带来的符号的歧义性 #include <iostream> #include <vector> using namespace std; class A { public:void f() { cout << "A" << endl; } }; class B { private:void f(); }; class C : public A, publ…

5.5.1哈夫曼树

知识总览&#xff1a; 概念&#xff1a; 结点的权&#xff1a;有某种现实含义的数值&#xff08;如&#xff1a;表示结点的重要性&#xff09; 结点的带权路径长度&#xff1a;从树的根到该结点的路径长度&#xff08;经过的边数&#xff09;与该结点上权值的乘积。 就比如说要…

ETL工具 - Kettle 案例,拉取网络列表数据

一、Kettle 实战案例 上篇文章对 Kettle 的查询、连接、统计、脚本算子进行了介绍&#xff0c;对 Kettle 的大部分算子都应该有了相应的了解&#xff0c;下面我们基于 Kettle 实战案例&#xff0c;拉取 CSDN 博客列表的全部数据&#xff0c;存放至 Excel 文件中。 实验之前先…

NECCS|全国大学生英语竞赛C类|词汇和语法|词汇题|21:03~21:53

词汇题 语法题 情景对话题 目录 一、词汇题 1. 基本词义辨析题 2. 同义词或近义词辨析题 3. 固定搭配 二、常见词组 一、词汇题 1. 基本词义辨析题 appropriate funds 拨款 slum- clearance programme 贫民窟清理计划 reject 拒绝接受&…

DAY 49 tomcat服务配置优化

什么是Tomcat Tomcat是Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的Web应用服务器&#xff0c;是Apache 软件基金会的 Jakarta 项目中的一个核心项目&#xff0c;由Apache、Sun和其他一些公司及人共同开发而成。 Tomcat属于轻量级应用服务器&#xff0…

外卖项目优化-02-

文章目录 瑞吉外卖项目优化-Day02课程内容前言1. MySQL主从复制1.1 介绍1.2 搭建1.2.1 准备工作1.2.2 主库配置1.2.3 从库配置 1.3 测试 2. 读写分离案例2.1 背景介绍2.2 ShardingJDBC介绍2.3 数据库环境2.4 初始工程导入2.5 读写分离配置2.6 测试 3. 项目实现读写分离3.1 数据…

深入解析PyTorch中的基本数据结构:张量的维度、形状和数据类型

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【LEAP模型】能源环境发展、碳排放建模预测及不确定性分析

本次内容突出与实例结合&#xff0c;紧密结合国家能源统计制度及《省级温室气体排放编制指南》&#xff0c;深入浅出地介绍针对不同级别研究对象时如何根据数据结构、可获取性、研究目的&#xff0c;构建合适的能源生产、转换、消费、温室气体排放&#xff08;以碳排放为主&…

【Spring框架全系列】Spring更简单的读取和存储对象

&#x1f4ec;&#x1f4ec;哈喽&#xff0c;大家好&#xff0c;我是小浪。上篇博客我们介绍了如何创建一个spring项目&#xff0c;并且如何的存、取对象&#xff0c;介绍了相关方法&#xff0c;那么本篇博客将接着上篇博客的内容介绍如何更加简单的读取和存储对象。 &#x1f…

从源码角度看Linux进程组和线程组

1.进程ID 线程组ID&#xff1a; 设置了CLONE_THREAD flag创建的进程(线程&#xff09;同属于同一个线程组&#xff0c;拥有同一个线程组ID(TGID)。pthread_create创建线程的时候&#xff0c;底层通过clone函数实现就指定了CLONE_THREAD参数&#xff0c;即一个进程中的各个线程…

前端搭建猜数字游戏(内附源码)

The sand accumulates to form a pagoda ✨ 写在前面✨ 功能介绍✨ 页面搭建✨ 样式设置✨ 逻辑部分✨ 完整代码 ✨ 写在前面 上周我们实通过前端基础实现了打字通&#xff0c;当然很多伙伴再评论区提出了想法&#xff0c;后续我们会考虑实现的&#xff0c;今天还是继续按照我…

架构设计-数据库篇

大家好&#xff0c;我是易安&#xff01; 之前我们讲过架构设计的一些原则&#xff0c;和架构设计的方法论&#xff0c;今天我们谈谈高性能数据库集群的设计与应用。 读写分离原理 读写分离的基本原理是将数据库读写操作分散到不同的节点上&#xff0c;下面是其基本架构图。 读…

【ansys】project may be corrupted and recovery information is available

一、问题背景 在网上找一个fluent算例打算在自己机器上运行。 打开fluent求解器&#xff0c;因为路径上有中文&#xff0c;在求解计算的时候出错了。 于是我通过任务管理器强制退出fluent和workbench程序&#xff0c;再将项目文件复制到一个没有中文的目录路径中。 重新打开…

15-2-线程-线程的创建,等待,退出

一、相关API 1. 线程创建 1. 线程创建 #include <pthread.h> int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);参数&#xff1a;参数1&#xff1a;&#xff08;创建的线程 的地址…

【JavaEE】TCP回写服务器简易翻译服务器(网络编程)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 上一篇我们讲解了UDP回写服务器和简易翻译服务器&#xff0c;想了解本篇文章&#xff0c;建议先看看上篇文章&#xff0c;学起来会更容易一些~~传送门&#xff1a;(1条消息) 【JavaEE】UDP数…

创新案例|香氛新品牌观夏如何以DTC模式仅4年实现年收过亿

国产香氛品牌观夏的DTC战略&#xff0c;正是从产品创新、全渠道布局、社交电商营销等方面创新&#xff0c;实现更高效地直接触达和转化消费者。观夏作为香氛DTC品牌的创新模式值得更多国内新品牌的关注与借鉴&#xff0c;同时也能为传统品牌的DTC转型提供全球化视野的启示。 1.…

改进YOLOv8: | ICLR 2022 | 涨点神器!Intel提出ODConv:即插即用的动态卷积 | 轻量化涨点创新必备

OMNI-DIMENSIONAL DYNAMIC CONVOLUTION ODConv实验核心代码修改文件yaml文件运行论文链接: https://openreview.net/forum?id=DmpCfq6Mg39 本文介绍了一篇动态卷积的工作:ODConv,其通过并行策略采用多维注意力机制沿核空间的四个维度学习互补性注意力。作为一种“即插即用…

3。数据结构(1)

嵌入式软件开发第三部分&#xff0c;各类常用的数据结构及扩展&#xff0c;良好的数据结构选择是保证程序稳定运行的关键&#xff0c;&#xff08;1&#xff09;部分包括数组&#xff0c;链表&#xff0c;栈&#xff0c;队列。&#xff08;2&#xff09;部分包括树&#xff0c;…

使用rt thread studio新建一个rt thread工程的详细操作说明(以stm32F411CEU6)为例

新建工程 这里以rt thread 5.0以及stm32F411CEU6芯片为例&#xff0c;创建工程 先建一个工作空间 .metadata是建工作空间自己生成的。 这时候&#xff0c;工作空间是空的&#xff0c;没有项目: 新建项目 首先下载RT-thread源文件和芯片支持包&#xff1a; 2023.05.02&#x…

NOIP2000 提高组 方格取数 线性DP 坐标优化 全局最优

&#x1f351; 算法题解专栏 &#x1f351; [NOIP2000 提高组] 方格取数 题目描述 设有 N N N \times N NN 的方格图 ( N ≤ 9 ) (N \le 9) (N≤9)&#xff0c;我们将其中的某些方格中填入正整数&#xff0c;而其他的方格中则放入数字 0 0 0。如下图所示&#xff08;见样…