Qt信号与槽机制的本质

2023-11-12

引入

对象与对象之间的通信有多个方式,如果我们要提供一种对象之间的通信机制。这种机制,要能够给两个不同对象中的函数建立映射关系,前者被调用时后者也能被自动调用。
再深入一些,两个对象如果都互相不知道对方的存在,仍然可以建立联系。甚至一对一的映射可以扩展到多对多,具体对象之间的映射可以扩展到抽象概念之间。这样子如何实现呢?

观察者模式

在我之前就介绍过设计模式之观察者模式,它就可以实现上述引入所讲的,两个对象如果都互相不知道对方的存在,仍然可以建立联系。归结到底就是回调函数+映射表的方式实现该思想。

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++编译期静态反射

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt信号与槽机制的本质 的相关文章

  • QTableView 中的虚拟列?

    我开始学习 Qt4 模型 视图编程 我有初学者问题 我有一个简单的应用程序 其中显示 sqlite 表QTableView class Model QtSql QSqlTableModel def init self parent None
  • 如何在 Qt-Embedded 中(正确)输出多语言文本?

    我的目标系统是 linux 3 3 7 Qt Embedded 开源版 4 8 Droid 字体 取自 fonts droid 20111207 git 1 all deb Debian 软件包并复制到 usr lib fonts目录 主要
  • Qt程序部署到多平台,如何?

    我是 Qt 编程新手 我想开发一个程序 我想在 Windows Linux ubuntu 和 Mac 上运行 听说Qt支持多平台应用程序开发 但我的问题是 在我部署或编译后 任何 Qt 库都需要在 Ubuntu 中运行这个应用程序吗 如果您
  • Qt中如何获取鼠标在屏幕上的位置?

    我想获取屏幕上的鼠标坐标 我怎样才能在 Qt 中做到这一点 在 Windows 上 使用 C 我正在做类似答案中建议的事情对于这个问题 https stackoverflow com q 11737665 1420197 正如文档所述 QC
  • Qt:将拖放委托给子级的最佳方式

    我在 QWidget 上使用拖放 我重新实现了 DragEnterEvent dragLeaveEvent dragMoveEvent 和 dropEvent 效果很好 在我的 QWidget 中 我有其他 QWidget 子级 我希望它们
  • Qt - 如何粘合两个窗口并将它们移动在一起?

    就像qmmp Qt 音乐播放器ui设计一样 这两个或三个窗口实际上在同一个窗口中 因为只有一个dock图标 并且这些窗口可以一起移动并相互附着 我看了源码 好像有用QDockWidget 但我真的不知道如何获得它的细节 当您手动移动辅助窗口
  • 禁用 QML Slider 的鼠标滚轮

    我希望能够滚动Flickable使用鼠标滚轮 或触摸板上的两根手指 不改变Sliders它可能包含 示例代码及结果应用 import QtQuick 2 7 import QtQuick Window 2 2 import QtQuick
  • 向 Qt 样式表添加特异性时丢失样式

    这是我的代码 const QString STYLE SHEET background color rgba x x x y border 1px solid gray border radius 0px border top 1px so
  • 如何创建用于 QML 的通用对象模型?

    我想知道是否有任何宏或方法如何将 Qt 模型注册为 QObject 的属性 例如 我有AnimalModel http doc qt io qt 5 qtquick modelviewsdata cppmodels html qabstra
  • 重定向 python 交互式帮助()

    我正在为使用 Qt 的应用程序开发交互式 python shell 但是我似乎无法获得重定向的交互式帮助 我的 python 代码中有这个 class OutputCatcher def init self self data def wr
  • 更改 Qt OpenGL 窗口示例以使用 OpenGL 3.3

    我正在尝试更改 Qt OpenGL 示例以使用更现代的 opengl 版本 330 似乎合适 所以我做了 在 main cpp 上设置版本和配置文件 设置着色器版本 更改着色器以使用统一 它现在构建没有任何错误 但我只看到一个空白窗口 我错
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • Qt:测量事件处理时间

    我想测量我的应用程序中的哪些事件在主线程中需要很长时间才能执行 阻塞 GUI 或者至少是否有任何事件花费的时间超过 比如说 10 毫秒 显然 我对需要很长时间的任务使用线程和并发 但有时很难在其他线程中放入的内容和可以保留在 GUI 中的内
  • Qt 插槽是否与其他代码并行运行?

    在此函数示例中 void MyClass myFunction emit MySignal1 emit MySignal2 如果我有slot1倾听MySignal1 and slot2倾听MySignal2 1 Is slot1总是会在之前
  • 将 gnuplot 嵌入现有 QtWidget 中

    我正在用 C 创建一个 伪 实时绘图应用程序 使用 gnuplot 作为绘图后端 我的要求之一是绘图必须位于现有窗口内 而不是有一个单独的绘图窗口 gnuplot 默认为 Gnuplot 有一个选项可以指定 Qt 小部件 ID 这似乎适合我
  • 如何使用meta-toolchain-qt5构建Qt(带有QtWebEngine支持)?

    我正在尝试使用构建 Qtmeta toolchain qt5 但是当我通过这样做时poky glibc x86 64 meta toolchain qt5 cortexa7hf vfp vfpv4 neon toolchain 2 0 1
  • 在高 dpi Windows 平台上自动重新缩放应用程序?

    我正在编写一个需要在高 dpi Windows 192dpi 而不是 96dpi 上运行的 Qt 应用程序 不幸的是 Qt 框架尚不支持高 dpi 至少在 Windows 上 因此我的应用程序及其所有元素看起来只有应有尺寸的一半 有没有办法
  • 如何为 Windows 构建静态 Qt 库并将其与 Qt Creator 一起使用

    我已经下载了以下 Qt 源 http download qt nokia com qt source qt everywhere opensource src 4 7 3 zip http download qt nokia com qt
  • 静态变量中的 qt tr()

    我在 qt 中的翻译方面遇到问题 我的项目中的所有翻译都工作正常 但有一个翻译位于类的静态变量中 相应部分代码如下 头文件类似于这样 typedef struct int type QString problematicString inf
  • 安装J语言的JQt IDE,出现错误

    我一直按照这里的说明进行操作 http code jsoftware com wiki System Installation Linux http code jsoftware com wiki System Installation L

随机推荐

  • 区块链技术栈-脚本系统

    脚本系统 脚本系统在区块链中是个比较抽象的概念 也是其中一个很重要的功能 可以说区块链系统之所以能形成一个有价值的网络 依靠的就是脚本系统 他就像是一个发动机一样 驱动着区块链系统不断进行着各种数据的收发 所谓脚本 就是指一组程序规则 在区
  • 使用scroll-view实现tabs(增加动画过渡效果)

    文章目录 前情提要 组件 scroll view 小程序项目 app json pages index index wxml pages index index wxss pages index index js 相关链接 前情提要 组件
  • IDEA操作技巧:一些常用且实用的插件

    CodeGlance 可帮助我们快速定位代码 下载之后会在IDEA的编辑区右侧显示一个代码进度条 设置方式 打开设置可以看到有一个codeGlance栏 点击可以进行设置 BackgroundImage 用于设置IDEA的背景图片 设置方式
  • Probabilistic Anchor Assignment with IoU Prediction for Object Detection论文阅读翻译 - 2020ECCV

    Probabilistic Anchor Assignment with IoU Prediction for Object Detection论文阅读翻译 目录 Probabilistic Anchor Assignment with I
  • 西门子plc s7-200写的先进先出范例 用fifo

    本人最近写了一个五台锅炉共用一个冷却水泵的程序 开始打算用时间戳来记录每台锅炉需要冷却的时间 然后用时间进行排序 但是后来无意中发现fifo可以实现表的先进先出的功能 就抱着学习的目的 用fifo写了本程序 第一步 先要建立一个表如下图 上
  • 分布式三高商城系统前言

    商城系统前言 前言 本商城致力于为中大型企业打造一个功能完整 易于维护的微服务B2B2C电商商城系统 采用主流的微服务技术实现 完全从零开始带领大家完成一个商城系统 包括基础的项目环境搭建 后端业务代码编写 前端页面等 微服务设计 mall
  • 多租户SaaS管理系统框架设计:多租户,多组织,用户区别

    数商云 已认证的官方帐号 转载自 多租户SaaS管理系统框架设计 多租户 多组织 用户区别 知乎 今天谈下云平台下的多租户架构 不论是在公有云还是私有云平台 是设计一个面向最终组织或用户的SaaS应用还是面向业务系统的PaaS平台 多租户都
  • 【物流配送的车辆路径问题】

    物流配送的车辆路径问题 提示 这里可以添加系列文章的所有文章的目录 目录需要自己手动添加 Two echelon capacitated vehicle routing problem with grouping constraints a
  • Human Gene Functions

    http acm hdu edu cn showproblem php pid 1080 Problem Description It is well known that a human gene can be considered as
  • leetcode刷题(10.22总结)

    1 丢失的数字 题目描述 https leetcode cn problems missing number class Solution def missingNumber self nums List int gt int n len
  • 基于SSM+MySQL在线书城项目

    目录 1 项目简介 2 项目说明 3 项目功能 4 项目展示 5 项目获取 1 项目简介 随着互联网发展 网上商城越来越活跃 线下购物方式逐渐弱化 在线购物越来越获得公众的欢迎 在线书城项目是一款B2C的线上购书系统 用户可以在本网站上购买
  • IDEA导入Web项目的三种方式

    文章目录 前言 一 第一种方式 二 第二种方式 三 第三种方式 前言 无论那种方式 它们都有相同的前提 那就是首先将你想要导入的Web项目放置在你想要导入的工程目录下 例如 举例子 笔者要将一个名为mavenWeb1的Web项目 笔者自己的
  • idm 服务器响应显示您没有权限下载此文件_玩转IDM,你不知道的IDM巧妙使用方法...

    在此前分享过的一系列百度网盘加速下载文章中 IDM Internet Download Manager 是不可或缺的一个环节 IDM 除了可以用来加速下载百度网盘资源外 其本身也是一款非常强大的下载器 它高速 精简 高效 把 一个程序做好一
  • 远程桌面控制台,有标签页可以管理多个远程桌面

    Server 2003系统自带远程桌面控制台 有标签页可以管理多个远程桌面 在windows的其他系统如果要实现可以参照以下操作 1 将server2003系统C WINDOWS system32目录下的mstsmhst dll mstsm
  • Android之 WebView的使用

    一 简介 1 1 WebView是用来展示网页的控件 底层是google的WebKit的引擎 比起苹果的WebView webkit一些不足地方 不能支持word等文件的预览 纯标签加载 并不支持所有标签的加载 不支持文件的下载 图片的放大
  • Elasticsearch 索引增删改

    添加小编微信 372787553 进入程序员技术交流群 本文已被 ElasticSearch从入门到入魔 收录 Elasticsearch 增删改 在前面我们已经安装好了elasticsearch 已经kibana 如果您还没有安装可以参考
  • 区块链倪老师:《区块链思维》第二章——“二维思维”的使用方法

    上回在 区块链思维 第一章中 我们已经从 一维思维 进阶到了 二维思维 今天我们就来讲讲如何使用 二维思维 二维思维 也叫结构化思维 顾名思义是将知识进行结构化的一种思维方式 同样 在区块链系统中 不同的部分分别构成了不同的结构 一般说来
  • 我的Android进阶之旅------>经典的大客推荐(排名不分先后)!!

    今天看到一篇文章 收藏了很多大牛的博客 在这里分享一下 转载于 http blog csdn net wujxiaoz article details 8237096 Android中文Wiki AndroidStudio NDK开发 移动
  • 思维导图系列——数据库

    思维导图系列 数据库 思维导图为博主期末复习亲自整理而成的 知识点覆盖全 可直接看思维导图复习 包含注解 图示等 觉得对你有帮助 不妨一键三连哦 链接见文末 参考书目 数据库系统概论 第5版 王珊 系列文章直达 思维导图系列 操作系统 思维
  • Qt信号与槽机制的本质

    引入 对象与对象之间的通信有多个方式 如果我们要提供一种对象之间的通信机制 这种机制 要能够给两个不同对象中的函数建立映射关系 前者被调用时后者也能被自动调用 再深入一些 两个对象如果都互相不知道对方的存在 仍然可以建立联系 甚至一对一的映