Qt信号与槽机制的本质
引入
对象与对象之间的通信有多个方式,如果我们要提供一种对象之间的通信机制。这种机制,要能够给两个不同对象中的函数建立映射关系,前者被调用时后者也能被自动调用。
再深入一些,两个对象如果都互相不知道对方的存在,仍然可以建立联系。甚至一对一的映射可以扩展到多对多,具体对象之间的映射可以扩展到抽象概念之间。这样子如何实现呢?
观察者模式
在我之前就介绍过设计模式之观察者模式,它就可以实现上述引入所讲的,两个对象如果都互相不知道对方的存在,仍然可以建立联系。归结到底就是回调函数+映射表的方式实现该思想。
qt的信号-槽
信号-槽 是Qt自定义的一种通信机制,它不同于标准C/C++ 语言,它的本质就是一种观察者模式的具体实现
信号-槽的使用方法,是在普通的函数声明之前,加上signal、slot标记,然后通过connect函数把信号与槽 连接起来。后续只要调用 信号函数,就可以触发连接好的信号或槽函数。

连接的时候,前面的是发送者,后面的是接收者。信号与信号也可以连接,这种情况把接收者信号看做槽即可。
信号与槽的分类
信号-槽要分成两种来看待,一种是同一个线程内的信号-槽,另一种是跨线程的信号-槽。
-
同一个线程内的信号-槽,就相当于函数调用,和前面的观察者模式相似,只不过信号-槽稍微有些性能损耗(因为需要查找映射表,这也是观察者解耦的代价)。
-
跨线程的信号-槽,在信号触发时,发送者线程将槽函数的调用转化成了一次“调用事件”,放入事件循环中。接收者线程执行到下一次事件处理时,处理“调用事件”,调用相应的函数。
信号与槽的实现 - 元对象编译器moc
信号-槽的实现,借助一个工具:元对象编译器MOC(Meta Object Compiler)。
这个工具被集成在了Qt的编译工具链qmake中,在开始编译Qt工程时,会先去执行MOC,从代码中解析signals、slot、emit等等这些标准C/C++不存在的关键字,以及处理Q_OBJECT、Q_PROPERTY、Q_INVOKABLE等相关的宏,生成一个moc_xxx.cpp的C++文件。比如信号函数只要声明、不需要自己写实现,就是在这个moc_xxx.cpp文件中,自动生成的。MOC之后就是常规的C/C++编译、链接流程了。
moc的本质-反射机制
MOC的本质,其实是一个反射器。标准C++没有反射功能(将来会有),所以Qt用moc实现了反射功能。
什么叫反射呢? 简单来说,就是运行过程中,获取对象的构造函数、成员函数、成员变量。
举个例子来说明,有下面这样一个类声明:
class Tom {
public:Tom() {}const std::string & getName() const{return m_name;}void setName(const std::string &name) {m_name = name;}
private:std::string m_name;
};
类的使用者,看不到类的声明,头文件都拿不到,不能直接调用类的构造函数、成员函数。
从配置文件拿到了一段字符串“Tom”,就要创建一个Tom类的对象实例。然后又拿到一段“setName”的字符串,就要去调用Tom的setName函数。
面对这种需求,就需要把Tom类的构造函数、成员函数等信息存储起来,还要能够被调用到。
这些信息就是 “元信息”,使用者通过“元信息”就可以“使用这个类”。这便是反射了。
设计模式中的“工厂模式”,就是一个典型的反射案例。不过工厂模式只解决了构造函数的调用,没有成员函数、成员变量等信息。
参考
学习反射看这一篇就够了
如何优雅的实现C++编译期静态反射
相关文章:
Qt信号与槽机制的本质
引入 对象与对象之间的通信有多个方式,如果我们要提供一种对象之间的通信机制。这种机制,要能够给两个不同对象中的函数建立映射关系,前者被调用时后者也能被自动调用。 再深入一些,两个对象如果都互相不知道对方的存在ÿ…...
Linux:入门学习知识及常见指令
文章目录 入门介绍操作系统的概念Linux机器的使用Linux上的指令 对文件知识的补充文件的定义和一些含义文件和目录的存储绝对路径和相对路径 ls指令pwd指令cd指令touch指令mkdir指令rmdir指令rm指令man指令cp指令mv指令cat指令more指令echo指令输出重定向 less指令find指令grep…...
K8s:Kubernetes 故障排除方法论
写在前面 博文内容为节译整理文中提到的工具大部分是商业软件,不是开源的,作为了解理解不足小伙伴帮忙指正 对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它…...
TCP 三次握手四次挥手浅析
大家都知道传输层中的TCP协议是面向连接的,提供可靠的连接服务,其中最出名的就是三次握手和四次挥手。 一、三次握手 三次握手的交互过程如下 喜欢钻牛角尖的我在学习三次握手的时候就想到了几个问题:为什么三次握手是三次?不是…...
【软件安装】MATLAB_R2021b for mac 安装
Mac matlab_r2021b 安装 下载链接:百度网盘 下载链接中所有文件备用。 我所使用的电脑配置: Macbook Pro M1 Pro 16512 系统 macOS 13.5 安装步骤 前置准备 无此选项者,自行百度 “mac 任何来源”。 1 下载好「MATLAB R2021b」安装文…...
电脑维护:10妙招,让你的电脑更加稳定!
你的电脑已经成为你工作、学习、娱乐的最佳工具之一,但是如果你不做好电脑维护工作,就可能面临着电脑变慢、蓝屏、崩溃等问题。在这篇文章中,我们将介绍10个电脑维护步骤,让你的电脑更加稳定! 为什么需要电脑维护&…...
大数据面试题:Kafka的单播和多播
面试题来源: 《大数据面试题 V4.0》 大数据面试题V3.0,523道题,679页,46w字 参考答案: 1、单播 一条消息只能被某一个消费者消费的模式称为单播。要实现消息单播,只要让这些消费者属于同一个消费者组即…...
python与深度学习(八):CNN和fashion_mnist二
目录 1. 说明2. fashion_mnist的CNN模型测试2.1 导入相关库2.2 加载数据和模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章训练的模型进行测…...
开发一个RISC-V上的操作系统(五)—— 协作式多任务
目录 往期文章传送门 一、什么是多任务 二、代码实现 三、测试 往期文章传送门 开发一个RISC-V上的操作系统(一)—— 环境搭建_riscv开发环境_Patarw_Li的博客-CSDN博客 开发一个RISC-V上的操作系统(二)—— 系统引导程序&a…...
Mybatis-plus集合
目录 mybatis-plus集合1、简介2、特性3、开始使用4、QueryWrapper的使用5、补充 mybatis-plus集合 1、简介 MyBatis-Plus (简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 m…...
C++ 结构体和联合体
1.结构体 结构体是一种特殊形态的类,它和类一样,可以有自己的数据成员和函数成员,可以有自己的构造函数和析构函数,可以控制访问权限,可以继承,支持包含多态,结构体定义的语法和类的定义语法几…...
使用TensorFlow训练深度学习模型实战(下)
大家好,本文接TensorFlow训练深度学习模型的上半部分继续进行讲述,下面将介绍有关定义深度学习模型、训练模型和评估模型的内容。 定义深度学习模型 数据准备完成后,下一步是使用TensorFlow搭建神经网络模型,搭建模型有两个选项…...
lucene、solr、es的区别以及应用场景
目录 1. Lucene:2. Solr:3. Elasticsearch: Lucene、Solr 和 Elasticsearch(ES) 都是基于 Lucene 引擎的搜索引擎,它们之间有相似之处,但也有一些不同之处。 Lucene 是一个低级别的搜索引擎库,它提供了一种用于创建和维护全文索引的 API&…...
Java方法的使用(重点:形参和实参的关系、方法重载、递归)
目录 一、Java方法 * 有返回类型,在方法体里就一定要返回相应类型的数据。没有返回类型(void),就不要返回!! * 方法没有声明一说。与C语言不同(C语言是自顶向下读取代码)&#…...
登录页的具体实现 (小兔鲜儿)【Vue3】
登录页 整体认识和路由配置 整体认识 登录页面的主要功能就是表单校验和登录登出业务 准备模板 <script setup></script><template><div><header class"login-header"><div class"container m-top-20"><h1 cl…...
大学如何自学嵌入式开发?
1. C语言:C语言是基础中的基础,刚开始学习不用太深入,一本常用的C语言的教材即可,注意不是当教科书看,而是看完一节过后,打开电脑把后面的习题都写出来,并且编译运行一遍,一定要动手…...
pytorch学习——线性神经网络——1线性回归
概要:线性神经网络是一种最简单的神经网络模型,它由若干个线性变换和非线性变换组成。线性变换通常表示为矩阵乘法,非线性变换通常是一个逐元素的非线性函数。线性神经网络通常用于解决回归和分类问题。 一.线性回归 线性回归是一种常见的机…...
00 - RAP 开发环境配置
文章目录 [1] Eclipse - ADT[2] BTP / S4HC[3] Add ABAP Env. Service[4] Conn. to BTP [1] Eclipse - ADT 关于如何安装配置,参见文章: Install ABAP Development Tools (ADT) and abapGit Plugin Eclipse Eclipse - ADT Eclipse - abapGit Plugin [2] BTP / S4…...
山西电力市场日前价格预测【2023-08-01】
日前价格预测 预测明日(2023-08-01)山西电力市场全天平均日前电价为310.15元/MWh。其中,最高日前电价为335.18元/MWh,预计出现在19: 45。最低日前电价为288.85元/MWh,预计出现在14: 00。 价差方向预测 1:实…...
QT--day5(网络聊天室、学生信息管理系统)
服务器: #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间servernew QTcpServer(this); }Widget::~Widget() {delete ui; …...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
