Qt应用开发(基础篇)——信号槽 Signals and Slots
一、前言
Qt成为我们今天拥有的灵活而舒适的工具,除了友好和能够快速开发设计师界面,信号槽机制是最大的核心特征,也是区别于其他开发框架最大的优势。
Qt的信号槽作用于两个对象之间的通信。当一个对象发生了改变,它希望其他关心它的对象能够了解到这些变化。比如一个编辑框A的数据发生了改变,而编辑框B的需要根据A的值发生数据变化,这时候我们使用信号槽机制,A产生数据变化信号,B响应信号做自身数据做改变。
我们用来表达算法的语法会显著影响代码的可读性和可维护性。Qt的信号和槽的语法在实践中被证明是非常成功的。语法直观,使用简单,易于阅读。这可以帮助程序员从一开始就正确地进行设计,甚至不必考虑设计模式。这满足安全和高效的图形用户界面编程,Qt希望我们构建更干净、更安全、更符合UNIX精神的系统。
二、Signals and Slots
要实现对象之间的通讯方法有很多。
1)初学者可能会通过定时器检测目标对象的属性变化而动作,这类方法缺点很明显,代码乱、耗资源、效率低、无法直接传递多个参数等等。
2)资深的程序员会使用回调callback机制,这是一种函数指针的用法,想让别人的代码执行自己的代码。把自身需要执行的代码写在一个函数里面,让目标对象去调用此函数,实现对象间的通讯。但是如果多对象类都想要关心目标对象的状态变化,此时需要维护一个列表,以存放多个回调函数的地址(函数指针),对于每一个被关注的对象,都需要做类似的工作,并且对象需要动态销毁的时候,还需要关注这些函数指针的回收,这样的设计效率低且不灵活。
3)信号槽机制类似于设计模式中的观察者模式(当一个对象状态发生改变的时候,所有依赖于它的对象都得到通知并被自动更新)。被观察者发出信号Signals,观察者监听信号,设计槽函数Slots关联信号实现动作。
值得一提的是,信号槽与回调函数的区别,是面试中经常出现的问题。
信号槽优点
1)松耦合性
目标对象不需要知道哪个对象关心自己,发出的信号类似于广播,如果有人对信号感兴趣,使用connect连接信号与自身的处理槽函数即可。而回调函数需要目标对象去处理对自己感兴趣的全部对象的函数指针。耦合性明显Qt信号槽机制更优。
2)类型安全
需要关联的信号槽的签名需要是相同的,即参数型号、参数个数必须一致。如果不一致的话编译器会报错。
3)灵活性
信号槽机制支持一个信号多个槽响应,也可以一个槽响应多个信号,还可以直接信号触发信号(适用于逻辑层信号夹带数据不需要处理直接转发)。
4)内存安全
信号槽机制在UI编程上具备优势,能够帮助程序员环节内存泄漏问题,当应用程序创建了一个具有父窗口部件的对象时,该对象被加入父窗口的child列表,当父窗口被销毁时,child列表中的对象被一一删除,子类释放的顺序与构造顺序相反。
信号槽缺点
1)速度较慢。
与回调函数相比,信号和槽机制运行速度比直接调用非虚函数慢10倍。照官方说法是需要定位接收信号的对象、需要遍历全部关联槽、需要编组和接祖传递参数。但依旧能够满足大多数应用的需求,因为1秒钟可以出发200万次这样的信号(i586-500机器,1个信号绑定一个槽函数,绑定两个1秒可以触发120万次)。
信号槽连接类型
connect连接信号槽第五个参数为连接类型,通常情况下默认为Qt::AutoConnection,自动设置。
类型 描述 Qt::AutoConnection 如果信号与槽在同一个线程中则为Qt::DirectConnection直连、否则为Qt::QueuedConnection队列。 Qt::DirectConnection 直连,发出信号的时候立刻调用槽函数 Qt::QueuedConnection 队列,信号与槽不同线程时,使用此类型 Qt::BlockingQueuedConnection 阻塞队列,等待槽函数返回,信号和槽不可在同一个线程,否则死锁 Qt::UniqueConnection 一个标识,与上述几种组合使用,避免相同信号槽多次连接
信号槽使用注意事项
1)默认情况下信号槽被多次连接,导致触发信号的时候槽函数就会被多次调用。可以使用Qt::UniqueConnection解决此问题。
2)Qt::BlockingQueuedConnection等于一个阻塞的机制,子线程执行信号必须等待主线程返回才会继续往下走,默认不阻塞。
3)多线程中,信号槽连接类型为Qt::QueuedConnection,所以信号触发的时候不会马上执行槽函数,存在实时性的风险。
4)信号触发的速度过快,而槽函数响应不过来。比如当你做一个视频播放器,摄像头的数据一直在刷新,但是界面上刷新不过来,槽函数处理的速度比不上信号触发的速度,如果这时候使用的是Qt::DirectConnection,导致程序可能异常。
5) 信号槽传递的参数必须是Qt的元对象系统所知道的类型,因为Qt需要复制参数以将它们存储在后台的事件中,否则编译会报错。如果需要使用自定义类型作为参数传递,使用Q_DECLARE_METATYPE()注册它。
6)所有信号的声明都是公有的,所以不能在signals前面加public,private,proteed
7)信号没有返回值,只需要声明不需要定义。
7)自定义类必须直接或间接继承自QObject类,并且开头私有声明包含Q_OBJECT,才能使用信号槽机制。
信号槽连接
1)传统写法-暴露参数
QLabel *label = new QLabel;
QScrollBar *scrollBar = new QScrollBar;
QObject::connect(scrollBar, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)));
//带连接类型
QObject::connect(scrollBar, SIGNAL(valueChanged(int)),label, SLOT(setNum(int)),Qt::AutoConnection);
2)进阶写法-隐藏参数
QLabel *label = new QLabel;
QLineEdit *lineEdit = new QLineEdit;
QObject::connect(lineEdit, &QLineEdit::textChanged,label, &QLabel::setText);//带连接类型
QObject::connect(lineEdit, &QLineEdit::textChanged,label, &QLabel::setText,Qt::AutoConnection);
3)直接触发当前函数
void someFunction();
QPushButton *button = new QPushButton;
QObject::connect(button, &QPushButton::clicked, someFunction);
//带连接类型
QObject::connect(button, &QPushButton::clicked, someFunction,
Qt::AutoConnection);
4)Lambda表达式
QByteArray page = ...;QTcpSocket *socket = new QTcpSocket;socket->connectToHost("qt-project.org", 80);QObject::connect(socket, &QTcpSocket::connected, [=] () {socket->write("GET " + page + "\r\n");});//带连接类型QObject::connect(socket, &QTcpSocket::connected, [=] () {socket->write("GET " + page + "\r\n");},Qt::AutoConnection);
识别信号来源
当有多个对象发送信号都通过一个槽来处理的时候,我们就需要在槽中识别出这些信号然后做相应的处理。
多个lineEdit编辑框当内容发送变化的时候,我们统一设计一个槽函数来做处理,使用sender()返回发送信号的指针。
void QMainWindows::textChaned(QString str)
{QLineEdit* edit = dynamic_cast<QLineEdit*>(sender())if (edit == ui->Edit_name){//do something }else if (edit == ui->Edit_number){//do something }
}
相关文章:

Qt应用开发(基础篇)——信号槽 Signals and Slots
一、前言 Qt成为我们今天拥有的灵活而舒适的工具,除了友好和能够快速开发设计师界面,信号槽机制是最大的核心特征,也是区别于其他开发框架最大的优势。 Qt的信号槽作用于两个对象之间的通信。当一个对象发生了改变,它希望其他关心…...
正则表达式--Notepad++常用的替换
原文网址:正则表达式--Notepad常用的替换_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Notepad使用正则表达式进行替换时的常用的一些示例。 服务器JSON的格式化 例1:将回车去掉,改为正确的JSON格式 搜索: ([^,])(\r)(\n)(\s) 替…...
ES6 对象合并
对象合并 在 JavaScript 中,可以使用不同的方法来合并对象的属性。这样可以将两个或多个对象的属性合并到一个新的对象中。这是在编程中常见的一种操作,尤其在处理配置、选项或数据更新时非常有用。 以下是几种常见的对象合并方法: 1. 使用…...

使用线性回归预测票房收入 -- 机器学习项目基础篇(10)
当一部电影被制作时,导演当然希望最大化他/她的电影的收入。但是我们能通过它的类型或预算信息来预测一部电影的收入会是多少吗?这正是我们将在本文中学习的内容,我们将学习如何实现一种机器学习算法,该算法可以通过使用电影的类型…...

一文读懂|RDMA原理
什么是DMA DMA全称为Direct Memory Access,即直接内存访问。意思是外设对内存的读写过程可以不用CPU参与而直接进行。我们先来看一下没有DMA的时候: 无DMA控制器时I/O设备和内存间的数据路径 假设I/O设备为一个普通网卡,为了从内存拿到需要…...

深入理解负载均衡原理及算法
1. 前言 在互联网早期,网络还不是很发达,上网用户少,流量相对较小,系统架构以单体架构为主。但如今在互联网发达的今天,流量请求动辄百亿、甚至上千亿,单台服务器或者实例已完全不能满足需求,这就有了集群。不论是为了实现高可用还是高性能,都需要用到多台机器来扩展服…...

44.实现爱尔兰B公式计算并输出表格(matlab程序)
1.简述 1.话务量定义 话务量指在一特定时间内呼叫次数与每次呼叫平均占用时间的乘积。 话务量反映了电话负荷的大小,与呼叫强度和呼叫保持时间有关。呼叫强度是单位时间内发生的呼叫次数,呼叫保持时间也就是占用时间。 话务量计算方法 话务量公式为…...

【Linux】-- 进程间通信
目录 一、进程间通信介绍 二、管道 1.什么是管道(pipe) 2.重定向和管道 (1)为什么要有管道的存在 (2)重定向和管道的区别 3.匿名管道 (1)匿名管道原理 (2&…...
[PyTorch][chapter 48][LSTM -3]
简介: 主要介绍一下 sin(x): 为 数据 cos(x): 为对应的label 项目包括两个文件 main.py: 模型的训练,验证,参数保存 lstm.py 模型的构建 目录: lstm.py main.py 一 lstm.py # -*- coding: utf-8 -*- "&q…...
xss csrf 攻击
介绍 xss csrf 攻击 XSS: XSS 是指跨站脚本攻击。攻击者利用站点的漏洞,在表单提交时,在表单内容中加入一些恶意脚本,当其他正常用户浏览页面,而页面中刚好出现攻击者的恶意脚本时,脚本被执行,从…...

如何使用win10专业版系统自带远程桌面公司内网电脑,从而实现居家办公?
使用win10专业版自带远程桌面公司内网电脑 文章目录 使用win10专业版自带远程桌面公司内网电脑 在现代社会中,各类电子硬件已经遍布我们身边,除了应用在个人娱乐场景的消费类电子产品外,各项工作也离不开电脑的帮助,特别是涉及到数…...
leetcode做题笔记62
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 问总共有多少条不同的路径? 思路一…...
图论 <最短路问题>模板
图论 <最短路问题> 有向图 1.邻接矩阵,稠密图 2.邻接表 (常用)单链表,每一个点都有一个单链表 ,插入一般在头的地方插, 图的邻接表的存储方式 树的深度优先遍历 特殊的深度优先搜索,…...

计算机网络性能指标
比特:数据量的单位 KB 2^10B 2^13 bit 比特率:连接在计算机网络上的主机在数字通道上传送比特的速率 kb/s 10^3b/s 带宽:信号所包含的各种频率不同的成分所占据的频率范围 Hz 表示在网络中的通信线路所能传送数据的能力(…...
vue + elementUI 实现下拉树形结构选择部门,支持多选,支持检索
vue elementUI 实现下拉树形结构选择部门,支持多选,支持检索 <template><div><el-select v-model"multiple?choosedValue:choosedValue[0]" element-loading-background"rgba(0,0,0,0.8)":disabled"disableFl…...

招投标系统简介 企业电子招投标采购系统源码之电子招投标系统 —降低企业采购成本 tbms
功能模块: 待办消息,招标公告,中标公告,信息发布 描述: 全过程数字化采购管理,打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力,为外…...

半监督学习(主要伪标签方法)
半监督学习 1. 引言 应用场景:存在少量的有标签样本和大量的无标签样本的场景。在此应用场景下,通常标注数据是匮乏的,成本高的,难以获取的,与之相对应的是却存在大量的无标注数据。半监督学习的假设:决策…...
datePicker一个或多个日期组件,如何快捷选择多个日期(时间段)
elementUI的组件文档中没有详细说明type"dates"如何快捷选择一个时间段的日期,我们可以通过picker-options参数来设置快捷选择: <div class"block"><span class"demonstration">多个日期</span><el…...
【语音合成】微软 edge-tts
目录 1. edge-tts 介绍 2. 代码示例 1. edge-tts 介绍 https://github.com/rany2/edge-tts 在Python代码中使用Microsoft Edge的在线文本到语音服务 2. 代码示例 import asyncio # pip install edge_tts import edge_tts TEXT """给我放首我喜欢听的歌曲…...

elevation mapping学习笔记3之使用D435i相机离线或在线订阅点云和tf关系生成高程图
文章目录 0 引言1 数据1.1 D435i相机配置1.2 协方差位姿1.3 tf 关系2 离线demo2.1 yaml配置文件2.2 launch启动文件2.3 数据录制2.4 离线加载点云生成高程图3 在线demo3.1 launch启动文件3.2 CMakeLists.txt3.3 在线加载点云生成高程图0 引言 elevation mapping学习笔记1已经成…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...