Qt 信号和槽的机制(逻辑清晰的来说清楚信号和槽,呕心沥血之作)

2023-11-16

Qt 信号和槽的机制

首先说声对不起,上次在PyQt5中写信号与槽,由于时间原因没有写完。有小伙伴留言说,希望把这章补全。所以,这是一篇迟来的文章,再次向大家说声抱歉。

一、桌面程序的结构

Qt的使用场景,主要是应用于桌面程序来使用,不管你使用的操作系统平台是什么。对于桌面程序来说,最重要的就是交互了。既然有交互,就需要一个窗口系统了。

窗口系统实现了桌面程序的主要逻辑,并提供了一套基于事件驱动的编程框架。Qt同样也提供了这样的一套逻辑。

我们常见的桌面程序的结构,如下图所示:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Yav5LiA5bed,size_20,color_FFFFFF,t_70,g_se,x_16

 所以,我们可以看到,在桌面程序中我们需要对窗口系统的一些操作作出相应,也就是事件。

二、事件

实现事件的机制通常有两种。

一种是事件处理类,是用回调函数来实现。

另一种叫委托,就是事件的处理不是收到事件的人自己来做,而是把它委托给了别人来做。Qt就提供了这样的一种机制:信号和槽。

三、信号和槽

信号与槽是Qt特有的的消息传输机制,在Qt中信号与槽用得十分广泛。在编程的过程中,我们都会遇到消息传递的事情,本质上就是发出命令(信号、消息),执行命令(相应的执行)。

比如单击窗口上一个按钮然后弹出一个对话框,那么就可以将这个按钮的单击信号和自定义的槽关联起来,信号是按钮的单击信号,槽实现了创建一个对话框并显示的功能。

信号与槽就是实现对象之间通信的一种机制,在其他编程语言中也有通过回调机制来实现对象之间的通信。

  • 信号:当对象改变其状态时,信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号。
  • 槽:用于接收信号,而且槽只是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。

信号槽是设计模式观察者模式的一种实现:

A、一个信号就是一个能够被观察的事件,或者至少是事件已经发生的一种通知;
B、一个槽就是一个观察者,通常就是在被观察的对象发生改变的时候——也可以说是信号发出的时候——被调用的函数;
C、信号与槽的连接,形成一种观察者-被观察者的关系;
D、当事件或者状态发生改变的时候,信号就会被发出;同时,信号发出者有义务调用所有注册的对这个事件(信号)感兴趣的函数(槽)。


信号和槽是多对多的关系。一个信号可以连接多个槽,而一个槽也可以监听多个信号。

然后,实现信号和槽,就要说一下Qt的元对象系统。

四、Qt元对象系统

Qt 的元对象系统叫 Mate-Object-System,提供了对象之间通信的信号与槽机制、运行时类型信息和动态属性系统。

但是,元对象是基于三个条件的:

 1、该类必须继承自Qobject类

 2、必须在类的私有声明区声明Q_OBJECT宏(在类定义的时候,如果没有指定public,
则默认为private,用来启用元对象功能,比如动态属性、信号和槽)。 

 3、 元对象编译器Meta-Object Compiler(moc)为 QObject的子类实现元对象 
特性提供必要的代码。

有了元对象系统后,我们就可以使用Qt的信号和槽了。

五、信号和槽的格式

信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:

QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

在Qt 5中提供了一种新的格式:

connect(sender, &Sender::valueChanged,receiver, &Receiver::updateValue);

具体的使用哪种格式,就看个人的喜好了。

注:在日常的项目编程中,如果第一种的connect方式出现报错,你可以尝试使用第二种connect方式。

六、connect的第五个参数

在connect函数中除了上面介绍的四个参数外,还有第五个参数,是缺省的参数。我们打开qobject.h文件可以看到它的定义,如下所示:

    static QMetaObject::Connection connect(const QObject *sender, const char *signal,
                const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);

    static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,
                const QObject *receiver, const QMetaMethod &method,
                Qt::ConnectionType type = Qt::AutoConnection);

    inline QMetaObject::Connection connect(const QObject *sender, const char *signal,
                const char *member, Qt::ConnectionType type = Qt::AutoConnection) const;

最后一个参数所表示的意思:

Qt::AutoConnection:信号的发送者与信号的接收者在同一线程,则默认使用Qt::DirectConnection:如果不在同一线程,则默认  使用Qt::QueuedConnection。
Qt::DirectConnection:信号的发送者与信号的接收者在同一线程中执行,当发出信号后,会马上进入槽函数,看上去就像在信号  发送位置调用了槽函数,在多线程下会比较危险,容易造成崩溃。
Qt::QueuedConnection:信号的发送者与信号的接收者不在同一线程中执行,槽函数运行于信号的接收者线程,当发送信号后,  槽函数不会马上被调用,等待信号的接收者把当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。
Qt::BlockingQueuedConnection:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
Qt::UniqueConnection:可以通过按位或(|)与以上四个结合在一起使用。当设置此参数时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。

介绍到这里,信号和槽的基本内容就写完了。但是,还是得说下Qt事件(你可以结合着上面第2节一起看)。

七、Qt事件

无论是什么桌面操作系统,每个进程都有一个全局的事件队列(Event Queue)。当我们在键盘上按了一个键、移动或者点击鼠标、触摸屏幕等等,都会产生一个事件(Event),并由操作系统负责将它扔到进程的事件队列。

扔到事件队列后,它会等待以后的某一个时刻发送。分配器(dispatcher )会遍历事件队列,并且将入栈的事件发送到它们的目标对象当中,因此它们被称为事件循环(Event loop)。

Qt中是通过运行QCoreApplication::exec()来进入Qt的主体事件循环的;这会引发阻塞,直至QCoreApplication::exit() 或者 QCoreApplication::quit() 被调用,进而结束循环。

写到这里就先结束吧,再次向大家说声抱歉,这篇迟来的文章-关于信号和槽的,欢迎大家一起交流一起进步。

本文原创作者:冯一川(ifeng12358@163.com),未经作者授权同意,请勿转载。

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

Qt 信号和槽的机制(逻辑清晰的来说清楚信号和槽,呕心沥血之作) 的相关文章

  • 安装多个版本的 Qt 库

    我在windows中安装了QtSDK 它的Qt库版本是4 7 0 现在我想为 mingw 和 VS2008 安装 Qt 库版本 4 8 2 我怎样才能做到这一点 如何向QtCreator引入多个版本 注意 我已经从以下位置下载了库http
  • Qt/c++ 随机字符串生成[重复]

    这个问题在这里已经有答案了 我正在创建一个应用程序 需要生成多个随机字符串 几乎就像一个由一定长度的 ASCII 字符组成的唯一 ID 这些字符混合有大写 小写 数字字符 有没有 Qt 库可以实现这一点 如果没有 在纯 C 中生成多个随机字
  • 如何在按下托盘图标菜单操作时执行功能?

    int main int argc char argv QApplication oApp argc argv QAction action1 QMenu menu QSystemTrayIcon TrayIcon QIcon favico
  • 如何创建QWidget的屏幕截图?

    我在 Qt Creator 中做作业 在其中绘制 QWidget 并且需要保存此 QWdiget 的某些部分 我试图解决这个问题 QPixmap pixmap pixmap copy rectangle rectangle is part
  • QT/QML Android App,点击通知栏时打开应用程序

    我为 Android 应用程序制作了一个 QT 当我单击平板电脑中上面看到的按钮通知栏时 但是 如果单击通知 我的应用程序将打开 聚焦 不知道 并显示黑色窗口 简单来说怎么做呢 我的代码是 package org ays operation
  • Qt中如何获取鼠标在屏幕上的位置?

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

    我在 QWidget 上使用拖放 我重新实现了 DragEnterEvent dragLeaveEvent dragMoveEvent 和 dropEvent 效果很好 在我的 QWidget 中 我有其他 QWidget 子级 我希望它们
  • QtCreator 调试暂停停在代码而不是汇编处

    如何配置 QtCreator 以便在调试并按下暂停时它会显示当前正在处理的代码 现在显示汇编 无法在任何地方找到有关此问题的答案 我使用的是 Windows 7 我在 Ubuntu 16 04 中使用 Qt Creator 4 2 2 时遇
  • QGraphicsScene::clear 不会改变 sceneRect

    我有一个 QGraphicsScene 场景 和 QGraphicsView graphicsView 我有一个画图的方法 当我需要重绘所有图形时 我调用这个方法 一切都好 但我意识到 scene gt clear 不会改变 sceneRe
  • Qt 文件对话框默认后缀不起作用

    我将以下代码用于 QtQuick Dialogs 1 3 和 Qt 5 10 0 下 filedialog 的新属性 我使用 Qt Creator 5 10 默认套件构建它 import QtQuick 2 10 import QtQuic
  • 为 Windows 98 编译 Qt

    我需要支持 Windows 98 Qt 文档声称这是可能的 但没有说明 Qt 4 6 的分布式二进制文件不能在 Win98 上运行 而且我采样的大多数 Qt 应用程序也不能在 Win98 上运行 对于几个确实在 98 上运行的应用程序 我询
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 如何在 QTabWidget Qt 中展开选项卡

    我有一个QTabWidget像这个 但我想展开选项卡以 填充 整个小部件宽度 如下所示 我怎样才能做到这一点 我在用Qt 5 3 2 and Qt 创建者 3 2 1 Update 我尝试使用setExpanding功能 ui gt myT
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • 无法在带有 QSortFilterProxyModel 的 QTreeView 的点击信号中使用 itemFromIndex

    我有一个 QTreeView 在视图和 QStandardItemModel 之间有一个 QSortFilterProxyModel 来对树进行排序 然后我想通过 clicked 信号对视图中的点击进行操作 模型 视图的设置类似于 mymo
  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • 从 Qt4 中的文本文件中逐字读取

    我想在 Qt4 中逐字读取一个文本文件 说实话我对它很陌生 我想在另一个文件中每行一个字写入 我可以在 C 中做到这一点 没有任何问题 但是当我尝试在 Qt4 中使用 ifstream 和 ofstream 时 我遇到了错误 这是我的 Qt
  • Qt 是否已经有了自己的 new 和 delete 运算符?

    我正在使用一个QGraphicsScene小部件并在其上显示一些点QGraphicsRectItem 这意味着要拨打很多电话new addItem 当出现时 并且removeItem delete摆脱未使用的点 当然 对于性能问题 我已经实
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table

随机推荐

  • 区块链开源实现HYPERLEDGER FABRIC架构详解

    写在前面 今天看了一篇讲解fabric架构的文章 感觉还不错 将fabric里的MSP和交易流程都讲的很明白 遂将文章在此分享 各位也可以直接看原文 也可以看我的 其中穿插了些本人拙见 原文地址 http www taohui pub 20
  • Going Deeper with convolutions

    Going Deeper with convolutions 转载请注明 http blog csdn net stdcoutzyx article details 40759903 本篇论文是针对ImageNet2014的比赛 论文中的方
  • 【原动力.降本增效】读后有感

    自我介绍 目前在一家算法加密公司担任项目经理 是从微信公众号火爆的那个年代开始接触 IT 互联网行业的 我的技术栈就不在这里介绍了 比较杂 因为前几家公司都是中小公司 那时候老板恨不得把设计也给开了 让你连画图带写页面 带写服务器后端功能
  • 慢SQL的致胜法宝

    大促备战 最大的隐患项之一就是慢SQL 对于服务平稳运行带来的破坏性最大 也是日常工作中经常带来整个应用抖动的最大隐患 在日常开发中如何避免出现慢SQL 出现了慢SQL应该按照什么思路去解决是我们必须要知道的 本文主要介绍对于慢SQL的排查
  • 【解决win10 64位系统下ISE14.7闪退问题】

    解决win10 64位系统下ISE14 7闪退问题 在FPGA开发中 使用Xilinx ISE设计工具可以快速进行开发 但是在使用win10 64位系统下的ISE14 7版本时 可能会遇到闪退的问题 这个问题很麻烦 但是可以通过一些简单的步
  • Cocos Shader实现纹理的动态波浪效果

    一 效果预览 通过滑动条可调节波浪频率的快慢 二 实现原理 对当前uv坐标进行线性 三角函数的混合变换 结合动态变化的时间值 得到一个新的采样坐标 使纹理呈现出动态 起伏不定的波浪形态 Shader中的关键代码如下 得到波浪效果的新坐标 v
  • VS code-设置问题

    起因 VS code本来是默认支持禁用非活动区域代码着色的 但我不知道怎么点取消了 今天又设置回来 因为感觉这样看代码方便点 方法 如果设置项旁边还有灰色小字提示与工作区不同 需要点一下将工作区设置也勾上 我就是只设置了用户区 没设置工作区
  • 搭配 umijs+vue的项目实战 以umijs为主应用+vue微应用

    这里写目录标题 搭配 umijs vue的项目实战 以umijs为主应用 vue微应用 umi js配置qiankun Vue2 x微应用 搭配 umijs vue的项目实战 以umijs为主应用 vue微应用 1 首先我们需要在项目中下载
  • 软件ETest

    ETest简介 ETest是一款软件开发环境IDE 基于该IDE可以完成嵌入式系统测试软件的开发与部署 该产品是由凯云科技率先在行业内推出的国产自主可控半实物仿真测试开发平台 有效打破了国内该领域长期由进口软件LabView DSpace等
  • 冲牙器使用记录

    保护好牙齿才能品尝美食 可以买一款比较便宜的冲牙器先试试 价位在100 200即可 一般有高中低三档 先用最低档位体验2个星期 冲的时候 喷嘴就贴着牙齿 不然会水花四溅
  • 51汇编——矩阵键盘

    矩阵按键可以说是51单片机一个比较典型的输入型的外设 它可以让人与单片机更好的进行交互 这一小节打算写一个4X4的矩阵按键 至于2X8 3X4 3X3 这些类型的其实他们的原理都是一样的 可以仿4X4的来写 矩阵按键扫描原理 这里使用的是8
  • 华为OD七日集训第5期 - 按算法分类,由易到难,循序渐进,玩转OD

    目录 一 适合人群 二 本期训练时间 三 如何参加 四 7日集训第5期 五 精心挑选21道高频100分经典题目 作为入门 第1天 逻辑分析 第2天 双指针 第3天 滑动窗口 第4天 贪心算法 第5天 二分查找 第6天 分治递归 第7天 搜索
  • 关于AI和ChatGPT的使用,AI编程(AIGC),AI绘画(3)

    使用AI绘画要注意哪些问题 1 版权和知识产权 使用别人的AI模型进行绘画可能会侵犯其版权和知识产权 需遵守相关法律法规 2 数据隐私 在使用AI绘画应用时 可能需要提供个人图像或图片等数据 要谨慎保护数据隐私 防止被滥用 3 算法可解释性
  • 移动端适配方案的优缺点比较

    当我们说到适配方案的时候越来越多的人会潜意识的翻译成移动端适配方案 确实是这样 在移动端蓬勃发展的今天 移动端的适配显得尤为重要 PC应用的适配已经不是适配方案主要需要考虑的了 随着移动互联网的来临 追求移动端的完美展示才是王道 最近也在做
  • 什么是三目运算符?三目运算符怎么使用?

    1 什么是三目运算符 三目运算符又称为 三元运算符 和 条件运算符 在java C C python JavaScript PHP等编程语言中都有三目运算符 三目运算符的作用就是判断 可以理解为if条件判断的简化版 2 三目运算符的运算规则
  • SQL数据分析概念与基础命令

    Parch Posey 数据库 实体关系图 实体关系图 ERD 是查看数据库中数据的常用方式 下面是我们将用于 Parch Posey 数据库的 ERD 这些图可帮助你可视化正在分析的数据 包括 表的名称 每个表中的列 表配合工作的方式 你
  • 蓝色巨人——IBM公司

    蓝色巨人 IBM之所以被称为蓝色巨人是因为他蓝色的徽标 还有IBM的深蓝超级计算机在第二次人机大战中胜出 IBM是为数不多的在成功逃过数次经济危机 并在历次技术革命中成功转型的公司之一 虽然他是大型计算机制作商 但是他已经过气了 不过他确是
  • 搞懂Vision Transformer 原理和代码,看这篇技术综述就够了(三)

    点击蓝字 关注极市平台 作者丨科技猛兽 来源丨极市平台 审核丨邓富城 极市导读 本文为详细解读Vision Transformer的第三篇 主要解读了两篇关于Transformer在识别任务上的演进的文章 DeiT与VT 它们的共同特点是避
  • 代码查看工具_F12 - 开发者工具详解

    学习使用浏览器自带的 F12 网页开发者工具 可以帮助前端以及测试人员来快速定位调试分析问题 解决问题 一 如何调出开发者工具 在浏览器页面上 F12 键 笔记本电脑 Fn F12 右键选择 检查 N 快捷键 Ctrl Shift i 二
  • Qt 信号和槽的机制(逻辑清晰的来说清楚信号和槽,呕心沥血之作)

    Qt 信号和槽的机制 首先说声对不起 上次在PyQt5中写信号与槽 由于时间原因没有写完 有小伙伴留言说 希望把这章补全 所以 这是一篇迟来的文章 再次向大家说声抱歉 一 桌面程序的结构 Qt的使用场景 主要是应用于桌面程序来使用 不管你使