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

【Qt】信号与槽(下)

目录

自定义信号

 带参数的信号和槽

信号和槽存在的意义

信号与槽的连接方式

一对一

一对多

多对一

意义

信号和槽的其他说明

信号和槽的断开

使用Lambda表达式定义槽函数

信号与槽的优缺点

优点: 松散耦合

缺点: 效率较低


自定义信号

自定义槽函数是非常关键的,在开发中大部分情况都是需要自定义槽函数的。

槽函数,就是用户触发某个操作之后,要进行的业务逻辑

自定义信号,比较少见,在实际开发中很少会需要自定义信号。

信号就对应到用户的某个操作。

在GUI,用户能够进行哪些操作,是可以穷举的,在Qt中内置的信号,基本已经覆盖到了上述所有可能的用户操作。因此使用Qt内置的信号,旧足以应付大部分的开发场景。

widget这个类中虽然没有定义任何信号,由于继承自Qwidget和QObject,这俩个类里面已经提供了一些信号,可以直接使用。

所谓的Qt信号,本质上就是一个”函数“。

        Qt5已经更高版本中,槽函数和普通的成员函数之间已经没有区别;但是信号则是一类特殊的函数:

  1. 只需要写出函数声明,并且告诉Qt这是一个”信号“即可,这个函数的定义,是Qt在编译过程中,自动生成的(自动生成的过程,程序员无法进行干预)。因为信号在Qt中式特殊的机制,Qt生成的信号函数的实现,要配合Qt框架左很多既定的操作。
  2. 作为信号函数,这个函数的返回值,必须式void,有没有参数都可以,甚至也可以支持重载。

这个signals也是Qt自己扩展出来的关键字,在qmake的时候,调用一些代码的分析/生成工具,扫描到类中包含signals这个关键字的时候,此时,就会自动的把下面的函数声明认为是信号,并且给这些信号函数自动的生成函数定义。

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();signals:void mySignal();public slots:void handleMySignaal();private:Ui::Widget *ui;
};
#endif // WIDGET_H

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this, &Widget::mySignal, this, &Widget::setWindowTitle);
}Widget::~Widget()
{delete ui;
}void Widget::handleMySignaal()
{this->setWindowTitle("自定义信号");
}

建立好联系之后,还需要将信号发送出去。

        对于Qt内置的信号,都不需要手动通过代码来触发,用户在GUI进行某些操作,就会自动触发对应信号(发射信号的代码已经内置到Qt框架中了)。

关键字:emit 发射

发射信号的操作,可以在任意合适的代码中。

这样就可以完成自定义信号了。

也可以通过点击按钮的方式,进行对窗口的编辑。

【注意】其实在Qt5中emit什么都不会做,真正进行操作的都包含在mysignal内部生成的函数定义里面,所以可以舍弃emit,信号也能发送出去,即使如此,在实际开发过程中,建议把emit加上,这可以让代码的可读性更高,更加明显的标识出这里发射自定义的信号。

 带参数的信号和槽

Qt的信号和槽也支持带有参数,同时也可以支持重载。

        此处要求:当信号带有参数的时候,槽的参数必须和信号参数一致,当发射信号的时候,就可以给信号函数传递实参,与之对应的这个参数就会被传递到槽函数里,此时就可以起到让信号给槽传参效果了。

【注意】在C++中声明函数的时候,形参的名字可以不用写。

        信号函数和槽函数必须一致,个数如果不一致也可以,当个数不一致的时候,要求信号参数的个数必须比槽的参数个数多。

传参可以起到复用代码代码的效果,如果有多个逻辑,逻辑上整体一致,但是涉及到的数据不同,就可以通过函数-参数来复用代码,并且在不同的场景中传入不同的参数。

通过这一套信号槽,搭配不同的参数,就可以起到设置不同标题的效果。

        在Qt的很多内置的信号,也是带有参数的,这些参数不是咱们自己传递的。

例如:clicked信号就带有一个参数。

clicked(bool),这个参数表示当前按钮是否处于“选中”状态。这个选中状态对于QPushButton没有意义,但是对于QCheckBox复选框是很有用的。

信号函数的参数个数,超过了槽函数的参数个数,还是可以正常使用的。

如果信号函数的参数个数少于槽函数的参数个数,此时代码无法编译通过。

为什么允许信号的参数比槽的参数多呢?

        一个槽函数,又可能会绑定多个信号。如果严格要求参数个数一致,就意味着信号绑定槽的要求就变高了。换而言之,当下这样的规则,就允许信号和槽之间的绑定更灵活了,有更多的信号可以绑定到这个槽函数上。

如果个数不一致,槽函数就会按照参数顺序,拿到信号的前N个参数。至少要确保,槽函数的每个参数都是有值的。所以要求信号给槽的参数,可以有富裕,但是不能少。

【注意】带有参数的信号,要求信号的参数和槽的参数一致,这里的一致指的是类型一致,个数满足要求(信号的参数个数要对于槽的参数个数)。

在Qt中,如果要让某个类能够使用信号槽(即可以在类中定义信号函数和槽函数),则必须在类最开始的地方,写下Q_OBJECT宏。

        这个事情可以看作是Qt中的硬性规定,这个宏能展开成很多额外的代码。

这里的宏还可以进一步展开,最后展开的效果会得到一系列很复杂的代码,此处就不深入研究了。

如果不加这个宏,代码在编译期间就会出错。

信号和槽存在的意义

所谓的信号和槽,最终要解决的问题,就是响应用户的操作。

信号与槽的连接方式

一对一

主要有俩种形式,分别是:一个信号连接一个槽和一个信号连接一个信号

一对多

一个信号连接多个槽

多对一

多个信号连接一个槽函数 

意义

一个信号,可以connect多个槽函数,一个槽函数也可以被多个信号connect。

        Qt引入信号与槽机制,最本质的目的就是为了能够让信号和槽之间按照“多对多”的方式进行关联。其他GUI框架是不具备这样的特性。但是,随着程序开发的经验变多,在GUI开发过程中,多对多这种情况,其实是”伪需求“,在实际开发中很少用到,绝大部分的情况,一对一就够用了。

信号和槽的其他说明

信号和槽的断开

使用disconnect即可完成断开,disconnect的用法和connect基本一致。

实际使用中,disconnect的使用比较少,大部分情况下把信号和槽连接上之后,就不用等了。

主动断开的目的往往是把信号重新绑定到另一个槽函数上。

  1. 断开原来的信号槽
  2. 重新绑定信号槽。

如果没有disconnect,就会构成一个信号绑定俩个槽函数,触发信号的时候,俩个槽函数都会执行。

使用Lambda表达式定义槽函数

Qt5在Qt4的基础上提高了信号与槽的灵活性,允许使用任意函数作为槽函数。但是如果想要方便的编写槽函数,例如在编写函数的时候连函数名都不想定义,就可以通过Lambda表达式来达到这个目的。

Lambda表达式是C++11增加的特性。在C++11中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作。

Lambda表达式的语法格式如下:

其本质上就是一个”匿名对象“,主要应用在”回调函数“场景中。

lambda表达式是一个回调函数,引入了”变量捕获“语法,通过变量捕获,获取到外层作用域中的变量。

在[ ]可以添加下面函数中需要的参数,如果想要使用外层的全部变量就需要[=]。

[=]这个写法的函数就是把上层作用域中的所有变量都给捕获进来。

#include "widget.h"
#include "ui_widget.h"#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button = new QPushButton("按钮" ,this);button->move(350, 250);connect(button, &QPushButton::clicked, this, [=](){this->setWindowTitle("lambda");button->setText("lambda");});
}Widget::~Widget()
{delete ui;
}

如果对应的槽函数比较简单,而且是一次性使用的,经常会写成lambda形式。

        另外也需要确认捕获到lambda内部的变量是由意义的,例如:无论何时用户点击了按钮,捕获到的变量都能正确使用。

信号与槽的优缺点

优点: 松散耦合

信号发送者不需要知道发出的信号被哪个对象的槽函数接收,槽函数也不需要知道哪些信号关联了⾃⼰,Qt的信号槽机制保证了信号与槽函数的调⽤。⽀持信号槽机制的类或者⽗类必须继承于QObject类。

缺点: 效率较低

与回调函数相⽐,信号和槽稍微慢⼀些,因为它们提供了更⾼的灵活性,尽管在实际应⽤程序中差别不⼤。通过信号调⽤的槽函数⽐直接调⽤的速度慢约10倍(这是定位信号的接收对象所需的开销;遍历所有关联;编组/解组传递的参数;多线程时,信号可能需要排队),这种调⽤速度对性能要求不是⾮常⾼的场景是可以忽略的,是可以满⾜绝⼤部分场景。

相关文章:

【Qt】信号与槽(下)

目录 自定义信号 带参数的信号和槽 信号和槽存在的意义 信号与槽的连接方式 一对一 一对多 多对一 意义 信号和槽的其他说明 信号和槽的断开 使用Lambda表达式定义槽函数 信号与槽的优缺点 优点: 松散耦合 缺点: 效率较低 自定义信号 自定义槽函数是非常关键的&a…...

多模态大语言模型(MMLLM)的现状、发展和潜力

1、大模型 随着ChatGPT流行&#xff0c;大模型技术正逐渐成为AI领域的热点。许多行业大佬纷纷投身于这一赛道&#xff0c;展示了大模型的独特魅力和广阔前景。 王慧文&#xff0c;前美团联合创始人&#xff0c;发起“AI英雄帖”。 李志飞&#xff0c;出门问问创始人&#xff0…...

Linux中apache服务安装与mysql安装

目录 一、apache安装 二、MySQL安装 一、apache安装 准备环境&#xff1a;一台虚拟机、三个安装包&#xff08;apr-1.6.2.tar.gz、apr-util-1.6.0.tar.gz、httpd-2.4.29.tar.bz2) 安装过程&#xff1a; tar xf apr-1.6.2.tar.gz tar xf apr-util-1.6.0.tar.gz tar xf http…...

Sublime Text常用快捷键

1. 简介 1.1. 概述 Sublime Text是一个轻量级的文本编辑器,它具有快速的启动速度、易用性以及美观的界面。它支持多种编程语言,并且可以通过各种插件进行功能扩展。Sublime Text由程序员Jon Skinner于2008年1月份开发出来,最初被设计为一个具有丰富扩展功能的Vim。它具有漂…...

高危漏洞CVE-2024-38077的修复指南

“ 根据2024年8月9日,国家信息安全漏洞共享平台(CNVD)收录了Windows远程桌面许可服务远程代码执行漏洞(CNVD-2024-34918,对应CVE-2024-38077)。未经身份认证的攻击者可利用漏洞远程执行代码,获取服务器控制权限。目前,该漏洞的部分技术原理和概念验证伪代码已公开,厂商…...

docker基本管理和应用

docker是一个开源的应用容器引擎&#xff0c;基于go语言开发的 docker是运行在linux的容器化工具&#xff0c;可以理解为轻量级的虚拟机 可以在任何主机上&#xff0c;轻松创建的一个轻量级&#xff0c;可移植的&#xff0c;自给自足的容器 鲸鱼--------->宿主机 集装箱…...

AI招聘在人才盘活中的作用:开启智慧人力新篇章

一、引言&#xff1a;AI赋能招聘新纪元 在21世纪的今天&#xff0c;随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到社会经济的各个角落&#xff0c;其中&#xff0c;人力资源管理领域也不例外。AI技术的引入&#xff0c;不仅颠覆了传统的招聘模…...

探索SD NAND配套测试工具:工程师的得力助手

在快速发展的存储技术领域&#xff0c;SD NAND因其高速读写、低功耗和高可靠性而广受青睐。然而&#xff0c;对于工程师来说&#xff0c;验证SD NAND的性能并非易事&#xff0c;为了便于工程师验证&#xff0c;MK 米客方德开发设计了SD NAND配套测试工具。 一、SD NAND转接板简…...

三十六、【人工智能】【机器学习】【监督学习】- Bagging算法模型

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…...

2024年8月8日(python基础)

一、检查并配置python环境&#xff08;python2内置&#xff09; 1、检测是否安装 [rootlocalhost ~]# yum list installed| grep python [rootlocalhost ~]# yum -y install epel-release 2、安装python3 [rootlocalhost ~]# yum -y install python3 最新版3.12可以使用源码安…...

SpringAOP_面向切面编程

一、什么是StringAOP AOP(Aspect-Oriented Programming: 面向切面编程)&#xff1a;将那些与业务无关&#xff0c; 却为业务模块所共同调用的逻辑&#xff08;例如事务处理、日志管理、权限控制等&#xff09;封装抽取成一个可重用的模块&#xff0c;这个模块被命名为“切面”&…...

芯片bring-up的测试用例

文章目录 前言一、测试用例的规划和编写原则1、冒烟测试1&#xff09;电源时钟复位测试2&#xff09;寄存器扫描测试3&#xff09;单一功能冒烟测试 二、遍历测试三、随机测试四、性能测试五、压力测试 总结 前言 最近做了一些用测试用例点亮芯片的工作&#xff0c;从测试用例…...

vs code编辑区域右键菜单突然变短

今天打开vs code发现鼠标在编辑区域按右键&#xff0c;出来的菜单只显示一小段 显示不全&#xff0c;而之前的样子是 显示很多项&#xff0c;怎么设置回到显示很多项呢&#xff1f;...

如何将TRIZ的“最终理想解”应用到机器人电机控制设计中?

TRIZ理论&#xff0c;作为一套系统的创新方法论&#xff0c;旨在帮助设计师和工程师突破思维惯性&#xff0c;解决复杂的技术难题。其核心思想之一便是“最终理想解”&#xff0c;它如同一盏明灯&#xff0c;指引着我们在技术创新的道路上不断前行。最终理想解追求的是产品或技…...

【记录】基于docker部署小熊派BearPi-Pico H3863开发环境

参考&#xff1a;&#x1f4dd; Ubuntu环境下开发环境搭建 | 小熊派BearPi 过程 在物理机中创建一个工作路径 /home/luo/locke/BearPi/BearPi_Pico_H3863创建docker容器 docker run -it \ --privilegedtrue --cap-addALL \ --name BearPi-Pico_H3863_env \ -v /home/luo/lo…...

Elasticsearch 与 OpenSearch:谁才是搜索霸主

Elasticsearch简介 Elasticsearch 是一个开源的、基于 RESTful 接口的分布式搜索和分析引擎&#xff0c;它利用了 Apache Lucene 的强大功能。 它特别适合处理大规模数据&#xff0c;这使得它成为管理和分析日志及事件数据的理想选择。 Elasticsearch 以其即时性而著称&…...

WEB渗透-TomcatAjp之LFIRCE

LFI https://github.com/Kit4y/CNVD-2020-10487-Tomcat-Ajp-lfi-Scanner >python CNVD-2020-10487-Tomcat-Ajp-lfi.py 192.168.0.110 -p 8009 -f pass配合目标文件上传传入服务器 RCE >msfvenom -p java/jsp_shell_reverse_tcp LHOST192.168.0.107 LPORT12138 R >/va…...

嵌入式初学-C语言-二一

数组指针 概念&#xff1a;数组指针是指向数组的指针。 特点&#xff1a; 先有数组&#xff0c;后有指针 它指向的是一个完整的数组。 一维数组指针 数据类型 (*指针变量名)[容量]&#xff1b; 案例&#xff1a; /** * 数组指针&#xff1a;指向数组的指针 */ #include <…...

2376. 统计特殊整数

Powered by:NEFU AB-IN Link 文章目录 2376. 统计特殊整数题意思路代码 2376. 统计特殊整数 题意 如果一个正整数每一个数位都是 互不相同 的&#xff0c;我们称它是 特殊整数 。 给你一个 正 整数 n &#xff0c;请你返回区间 [1, n] 之间特殊整数的数目。 思路 详见灵神…...

Python 绘图进阶之核密度估计图:掌握数据分布的秘密

Python 绘图进阶之核密度估计图&#xff1a;掌握数据分布的秘密 引言 在数据分析中&#xff0c;了解数据的分布情况是至关重要的一步。除了常用的直方图和箱线图&#xff0c;核密度估计图&#xff08;Kernel Density Estimation, KDE&#xff09;提供了一种更为平滑、直观的方…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散

前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说&#xff0c;在叠衣服的过程中&#xff0c;我会带着团队对比各种模型、方法、策略&#xff0c;毕竟针对各个场景始终寻找更优的解决方案&#xff0c;是我个人和我司「七月在线」的职责之一 且个人认为&#xff0c…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...

热门Chrome扩展程序存在明文传输风险,用户隐私安全受威胁

赛门铁克威胁猎手团队最新报告披露&#xff0c;数款拥有数百万活跃用户的Chrome扩展程序正在通过未加密的HTTP连接静默泄露用户敏感数据&#xff0c;严重威胁用户隐私安全。 知名扩展程序存在明文传输风险 尽管宣称提供安全浏览、数据分析或便捷界面等功能&#xff0c;但SEMR…...

【Ftrace 专栏】Ftrace 参考博文

ftrace、perf、bcc、bpftrace、ply、simple_perf的使用Ftrace 基本用法Linux 利用 ftrace 分析内核调用如何利用ftrace精确跟踪特定进程调度信息使用 ftrace 进行追踪延迟Linux-培训笔记-ftracehttps://www.kernel.org/doc/html/v4.18/trace/events.htmlhttps://blog.csdn.net/…...

【java】【服务器】线程上下文丢失 是指什么

目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失&#xff1f; 直观示例说明 为什么上下文如此重要&#xff1f; 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程&#xff0c;代码应该如何实现 推荐方案&#xff1a;使用 ManagedE…...

Java设计模式:责任链模式

一、什么是责任链模式&#xff1f; 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09; 是一种 行为型设计模式&#xff0c;它通过将请求沿着一条处理链传递&#xff0c;直到某个对象处理它为止。这种模式的核心思想是 解耦请求的发送者和接收者&#xff0c;…...

6.9本日总结

一、英语 复习默写list11list18&#xff0c;订正07年第3篇阅读 二、数学 学习线代第一讲&#xff0c;写15讲课后题 三、408 学习计组第二章&#xff0c;写计组习题 四、总结 明天结束线代第一章和计组第二章 五、明日计划 英语&#xff1a;复习l默写sit12list17&#…...