当前位置: 首页 > news >正文

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成为我们今天拥有的灵活而舒适的工具&#xff0c;除了友好和能够快速开发设计师界面&#xff0c;信号槽机制是最大的核心特征&#xff0c;也是区别于其他开发框架最大的优势。 Qt的信号槽作用于两个对象之间的通信。当一个对象发生了改变&#xff0c;它希望其他关心…...

正则表达式--Notepad++常用的替换

原文网址&#xff1a;正则表达式--Notepad常用的替换_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Notepad使用正则表达式进行替换时的常用的一些示例。 服务器JSON的格式化 例1&#xff1a;将回车去掉&#xff0c;改为正确的JSON格式 搜索&#xff1a; ([^,])(\r)(\n)(\s) 替…...

ES6 对象合并

对象合并 在 JavaScript 中&#xff0c;可以使用不同的方法来合并对象的属性。这样可以将两个或多个对象的属性合并到一个新的对象中。这是在编程中常见的一种操作&#xff0c;尤其在处理配置、选项或数据更新时非常有用。 以下是几种常见的对象合并方法&#xff1a; 1. 使用…...

使用线性回归预测票房收入 -- 机器学习项目基础篇(10)

当一部电影被制作时&#xff0c;导演当然希望最大化他/她的电影的收入。但是我们能通过它的类型或预算信息来预测一部电影的收入会是多少吗&#xff1f;这正是我们将在本文中学习的内容&#xff0c;我们将学习如何实现一种机器学习算法&#xff0c;该算法可以通过使用电影的类型…...

一文读懂|RDMA原理

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

深入理解负载均衡原理及算法

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

44.实现爱尔兰B公式计算并输出表格(matlab程序)

1.简述 1.话务量定义 话务量指在一特定时间内呼叫次数与每次呼叫平均占用时间的乘积。 话务量反映了电话负荷的大小&#xff0c;与呼叫强度和呼叫保持时间有关。呼叫强度是单位时间内发生的呼叫次数&#xff0c;呼叫保持时间也就是占用时间。 话务量计算方法 话务量公式为…...

【Linux】-- 进程间通信

目录 一、进程间通信介绍 二、管道 1.什么是管道&#xff08;pipe&#xff09; 2.重定向和管道 &#xff08;1&#xff09;为什么要有管道的存在 &#xff08;2&#xff09;重定向和管道的区别 3.匿名管道 &#xff08;1&#xff09;匿名管道原理 &#xff08;2&…...

[PyTorch][chapter 48][LSTM -3]

简介&#xff1a; 主要介绍一下 sin(x)&#xff1a; 为 数据 cos(x): 为对应的label 项目包括两个文件 main.py: 模型的训练&#xff0c;验证&#xff0c;参数保存 lstm.py 模型的构建 目录&#xff1a; lstm.py main.py 一 lstm.py # -*- coding: utf-8 -*- "&q…...

xss csrf 攻击

介绍 xss csrf 攻击 XSS&#xff1a; XSS 是指跨站脚本攻击。攻击者利用站点的漏洞&#xff0c;在表单提交时&#xff0c;在表单内容中加入一些恶意脚本&#xff0c;当其他正常用户浏览页面&#xff0c;而页面中刚好出现攻击者的恶意脚本时&#xff0c;脚本被执行&#xff0c;从…...

如何使用win10专业版系统自带远程桌面公司内网电脑,从而实现居家办公?

使用win10专业版自带远程桌面公司内网电脑 文章目录 使用win10专业版自带远程桌面公司内网电脑 在现代社会中&#xff0c;各类电子硬件已经遍布我们身边&#xff0c;除了应用在个人娱乐场景的消费类电子产品外&#xff0c;各项工作也离不开电脑的帮助&#xff0c;特别是涉及到数…...

leetcode做题笔记62

一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff1f; 思路一…...

图论 <最短路问题>模板

图论 <最短路问题> 有向图 1.邻接矩阵&#xff0c;稠密图 2.邻接表 &#xff08;常用&#xff09;单链表&#xff0c;每一个点都有一个单链表 &#xff0c;插入一般在头的地方插&#xff0c; 图的邻接表的存储方式 树的深度优先遍历 特殊的深度优先搜索&#xff0c…...

计算机网络性能指标

比特&#xff1a;数据量的单位 KB 2^10B 2^13 bit 比特率&#xff1a;连接在计算机网络上的主机在数字通道上传送比特的速率 kb/s 10^3b/s 带宽&#xff1a;信号所包含的各种频率不同的成分所占据的频率范围 Hz 表示在网络中的通信线路所能传送数据的能力&#xff08…...

vue + elementUI 实现下拉树形结构选择部门,支持多选,支持检索

vue elementUI 实现下拉树形结构选择部门&#xff0c;支持多选&#xff0c;支持检索 <template><div><el-select v-model"multiple?choosedValue:choosedValue[0]" element-loading-background"rgba(0,0,0,0.8)":disabled"disableFl…...

招投标系统简介 企业电子招投标采购系统源码之电子招投标系统 —降低企业采购成本 tbms

​功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外…...

半监督学习(主要伪标签方法)

半监督学习 1. 引言 应用场景&#xff1a;存在少量的有标签样本和大量的无标签样本的场景。在此应用场景下&#xff0c;通常标注数据是匮乏的&#xff0c;成本高的&#xff0c;难以获取的&#xff0c;与之相对应的是却存在大量的无标注数据。半监督学习的假设&#xff1a;决策…...

datePicker一个或多个日期组件,如何快捷选择多个日期(时间段)

elementUI的组件文档中没有详细说明type"dates"如何快捷选择一个时间段的日期&#xff0c;我们可以通过picker-options参数来设置快捷选择&#xff1a; <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已经成…...

StructBERT情感分类实操手册:自定义示例文本添加方法

StructBERT情感分类实操手册&#xff1a;自定义示例文本添加方法 1. 引言&#xff1a;为什么需要自定义示例&#xff1f; 当你第一次打开StructBERT情感分类的Web界面&#xff0c;可能会觉得它已经内置了不少例子&#xff0c;用起来挺方便。但用着用着&#xff0c;你就会发现…...

Vue 过滤器详解及 Vue 3 中的替代方案

Vue 过滤器详解及 Vue 3 中的替代方案 一、Vue 过滤器的核心概念与特性 Vue 过滤器&#xff08;Filter&#xff09;是 Vue 2.x 提供的用于数据格式化转换的机制&#xff0c;其核心设计理念是不修改原始数据&#xff0c;仅对显示层进行格式化处理。过滤器本质上是纯函数&#xf…...

MAX30102传感器寄存器深度解析与实战配置指南

1. MAX30102传感器核心功能解析 MAX30102是一款集成了红光和红外光LED的光学传感器&#xff0c;专门用于非侵入式心率监测和血氧饱和度(SpO2)测量。这个火柴盒大小的芯片内部藏着精密的模拟前端和数字信号处理单元&#xff0c;能够捕捉到人体脉搏带来的微弱光信号变化。 我第一…...

Leather Dress Collection 模型Java后端集成指南:SpringBoot微服务开发

Leather Dress Collection 模型Java后端集成指南&#xff1a;SpringBoot微服务开发 最近在做一个电商相关的项目&#xff0c;需要集成一个能生成皮革服饰设计图的AI模型&#xff0c;正好接触到了Leather Dress Collection。作为后端开发&#xff0c;我的第一反应就是&#xff…...

纹理识别必备!5个高质量数据集下载与使用指南(附避坑技巧)

纹理识别实战指南&#xff1a;五大高价值数据集深度解析与应用技巧 纹理识别作为计算机视觉领域的重要分支&#xff0c;在工业质检、自动驾驶、医疗影像等场景中发挥着关键作用。但许多开发者在数据集获取和预处理阶段就会遇到各种"暗坑"——从下载链接失效到标注格式…...

自编码器在异常检测中的实战:如何用TensorFlow识别异常数据点

自编码器在异常检测中的实战&#xff1a;如何用TensorFlow识别异常数据点 金融交易中的一笔异常转账、工业设备传感器突然的读数波动、医疗影像中微小的病变区域——这些隐藏在庞大数据流中的异常信号&#xff0c;往往预示着关键风险或机会。传统基于阈值规则的检测方法在面对高…...

Android Qcom USB Driver学习(十):Type-C充电管理与ADSP电源架构深度解析

1. Type-C充电管理在高通平台的核心架构 高通平台的Type-C充电管理采用分层设计&#xff0c;最上层是Generic TypeC Driver PowerSupply Framework&#xff0c;作为Linux内核与硬件之间的抽象层。这个框架负责统一管理充电策略、电源角色切换和状态上报。中间层通过Glink通信协…...

在国产麒麟V10系统上,用kubeadm一步步搭建3个master节点的k8s高可用集群(含haproxy+keepalived配置)

国产麒麟V10系统上构建高可用Kubernetes集群实战指南 在信息技术自主可控的大背景下&#xff0c;国产操作系统正逐步成为企业级基础设施的重要选择。本文将详细介绍如何在麒麟V10&#xff08;Kylin V10&#xff09;操作系统上&#xff0c;从零开始搭建一个包含3个Master节点的高…...

AI 创作者指南:09.AI 作为你的创作运营助理

第 9 篇 AI 作为你的创作运营助理 多模态魔法刚玩完,你现在一篇文章能变10种形态,是不是已经觉得内容像会“分身术”了?😊 来,第三部分继续!第9篇——AI 作为你的创作运营助理。 以前你自己盯排期、想矩阵、试标题,累得像管家婆。现在AI直接当你的“运营小秘书”,帮你…...

PyQt5实战:用QTreeView+QStandardItemModel快速构建你的第一个树形文件浏览器(附完整代码)

PyQt5实战&#xff1a;用QTreeViewQStandardItemModel快速构建你的第一个树形文件浏览器 每次看到电脑资源管理器左侧那整齐的目录树&#xff0c;你是否好奇过它是如何实现的&#xff1f;今天我们就用PyQt5的QTreeView和QStandardItemModel组件&#xff0c;从零开始打造一个简…...