初识Qt · 信号与槽 · 基础知识

目录

前言:

信号和槽初识

两个问题


前言:

本文我们正式开始介绍信号与槽这个概念,在谈及Qt中的信号与槽这个概念之前,我们不妨回顾一下Linux中的信号,比如发生了除0错误,OS就会给该进程发送一个信号,使该进程终止。

那么Linux中涉及信号的时候,涉及到了谁发出的,什么信号,执行的行为,谁接受的。在我们前文熟悉Qt的整个框架的时候,使用的函数connect,参数分别就是上面涉及到了四个点,所以实际上Qt中的信号和Linux中的信号是有很多相同点的,那么有了Linux的基础,在这里学习Qt我们就要轻松很多了。


信号和槽初识

说到底,我们现在还是没有理解什么是槽,什么是信号,这里先给一个结论:

信号和槽都是函数

但是,为什么信号是函数这里并不打算展开来说,我们在这里能理解的是槽是函数,那么也就是说,某个控件接收到了某个信号,就要执行对应的槽函数,那么我们为什么控件知道接收到了某个信号就应该执行某个槽函数呢?

这是因为connect将槽函数和信号关联在了一起。

那么槽和信号的触发顺序是什么呢?我们不妨举个女朋友在一个月中总有那么不舒服的几天,当我们接收到了女朋友不舒服的这个信号,我们就应该知道我们该倒红糖水,该揉揉肚子什么的。

所以对于信号和槽的一个处理顺序来看,我们就应该知道,在信号处理之前,我们一定要有槽函数的这个定义,如果没有定义,我们就错过了这个信号的处理,自然而言的,女朋友的”蜀道难“也就来了。

那么我们回到Qt就知道,connect函数实际上是一个回调函数,信号是函数吧?槽是函数吧?那么这两个函数作为了connect函数的参数,也就成就了一个典型回调函数。

那么既然介绍到了connect,对于参数部分我们就不用提及了,对于C++中的库函数我们都是知道来源于谁的,那么connect函数是来源于谁呢?

牵扯到了这个问题,我们就不得不谈一谈Qt中的一个继承关系,拿隔壁java举例,我们知道java的所有类都继承于一个专门的类,叫做Object,在Qt中也有一个类似的设定,即QObject是所有内置类的祖宗:

那么connect函数呢就是QObject中的一个静态成员函数。

 //connect to a functor, with a "context" object defining in which event loop is going to be executedtemplate <typename Func1, typename Func2>static inline typename std::enable_if<QtPrivate::FunctionPointer<Func2>::ArgumentCount == -1, QMetaObject::Connection>::typeconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,Qt::ConnectionType type = Qt::AutoConnection)

这是它的一个函数定义。

对于我们之前看到的connect函数好像又有所不同,我们之前使用的connect函数好像没有那么复杂,我们之前使用Qt函数的原型是:

可是你看上面的类型,好像无论如何都没有办法和char*打上交道,对于第一个和第三个来说多正常,因为这两个参数是接收控件的嘛,子类赋值给基类,非常正常,可是其他参数呢?

之前使用第二个和第四个的参数可是函数指针类型,和char*是一点没有关系的,这怎么能够防在一起?实际上两个宏有关,一个是给槽函数传参的时候要搭配一个SLOT宏,一个是给信号函数传参的时候需要搭配一个SIGNAL宏。这两个宏可以让传入的指针变成char*。所以以前写的时候,是这样使用connect函数的:

connect(button,SIGNAL(&QPushButton::clicked),this,SLOT(&Widget::close));

但是这个写法是Qt4之前的了,对于新版的Qt就不用这样写了,实在是麻烦,新版的Qt5支持了一个重载版本,使得第二个和第四个参数变成了泛型指针,我们也就不用宏了,当然你要想那样写应该也没事儿~

这个时候的Qt就有了一个类型检查的功能,在上文提供的一个源码来说:

const typename QtPrivate::FunctionPointer<Func1>::Object *sender

这是一个类型萃取器,如果传入的参数第一个和第二个不匹配,第三个和第四个不匹配,主要指的是函数指针,编译就会报错了~当然,这里我们了解一下就行。

现在我们来了解一下信号,我们会发现之前使用button的信号的时候,有两个click,一个是过去分词形式,一个是动词形式:

其中这个锯齿形状的就是slot函数,也就是槽函数,比如我触发了一个信号,然后某个按钮就click了,对于波纹状的就是信号函数,是我们点击了,然后触发了信号。

这是二者的区别。

对于connect函数来说,第一个和第二个的参数类型应该是匹配的,第一个比如是button,第二个就应该是父类的信号,不能是其他的,比如QLineEdit的。

以上是对connect函数的一个简单理解。

实际上在以前老版本的时候,实现槽函数应该在前面加:
 

public slot:void Handle();

但是现在不用了~你要想也可以~ 


如何查阅

我咋知道QPushButton中有个clicked信号?我咋知道QWidget有个close槽?

也就是我们可以延展到我们怎么翻阅文档?

直接就是打开一手assistant,从中我们直接在索引部分找QPushButtion,但是我们似乎翻遍了文档也没有找到clicked信号。

这其实是因为clicked是继承于它的父类的,那么我们从哪里进到父类呢?

Inherits是继承,也就是说该类是继承于QAbstractButton的,下面的同理,我们点进去看看:

就可以看到它同样是继承了别的类的。

往下滑动就可以看到对应的槽函数和信号函数了,那么信号函数的缺省值我们不用管,稍微想想也能相通。

以上是对信号和槽的一个简单知识输出。


感谢阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/71428.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kotlin 5种单例模式

在Kotlin中实现单例模式有多种方法&#xff0c;以下是几种常见的方法&#xff1a; 饿汉式 饿汉式是最简单的一种实现方式&#xff0c;在类加载时就完成了实例的初始化。 //饿汉式 object Singleton1 {fun printMessage() {println("饿汉式")} }懒汉式 懒汉式是延迟…

探秘基带算法:从原理到5G时代的通信变革【一】引言

文章目录 一、引言1.1 研究背景与意义1.2 研究目的与方法1.3 研究内容与创新点 本博客为系列博客&#xff0c;主要讲解各基带算法的原理与应用&#xff0c;包括&#xff1a;viterbi解码、Turbo编解码、Polar编解码、CORDIC算法、CRC校验、FFT/DFT、QAMtiaozhi/解调、QPSK调制/解…

C/C++输入输出(1)

1.getchar和putchar 1.1getchar() 函数原型&#xff1a; 1 int getchar(void); getchar()函数返回用户从键盘输入的字符&#xff0c;使用时不带有任何参数。 程序运行到这个命令就会暂停&#xff0c;等待用户从键盘输入&#xff0c;等同于使用cin或scanf()方法读取一个字符…

【消息队列】数据库的数据管理

1. 数据库的选择 对于当前实现消息队列这样的一个中间件来说&#xff0c;具体要使用哪个数据库&#xff0c;是需要稍作考虑的&#xff0c;如果直接使用 MySQL 数据库也是能实现正常的功能&#xff0c;但是 MySQL 也是一个客户端服务器程序&#xff0c;也就意味着如果想在其他服…

飞机大战lua迷你世界脚本

-- 迷你世界飞机大战 v1.2 -- 星空露珠工作室制作 -- 最后更新&#xff1a;2024年1月 ----------------------------- -- 迷你世界API适配配置 ----------------------------- local UI { BASE_ID 7477478487091949474-22856, -- UI界面ID ELEMENTS { BG 1, -- 背景 BTN_LE…

图解MOE大模型的7个核心问题并探讨DeepSeekMoE的专家机制创新

原文地址:https://newsletter.maartengrootendorst.com/p/a-visual-guide-to-mixture-of-experts #mermaid-svg-FU7YUSIfuXO6EVHa {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-FU7YUSIfuXO6EVHa .error-icon{fill…

【智能机器人开发全流程:硬件选型、软件架构与ROS实战,打造高效机器人系统】

文章目录 1. 硬件层设计(1) 传感器选型(2) 计算平台 2. 软件架构设计(1) 核心模块划分(2) 通信框架 3. 关键实现步骤(1) 硬件-软件接口开发(2) SLAM与导航实现(3) 仿真与测试 4. 典型框架示例基于ROS的移动机器人分层架构 5. 优化与扩展6. 开源项目参考 1. 硬件层设计 (1) 传感…

React Native v0.78 更新

这个版本在 React Native 中引入了 React 19&#xff0c;并带来了一些重要的新功能&#xff0c;例如 Android 矢量图&#xff08;Vector Drawables&#xff09;的原生支持 以及 iOS 更好的 Brownfield 集成。 亮点 React 19 集成更小更快的发布节奏可选择在 Metro 中启用 Jav…

机器学习数学通关指南

✨ 写在前面 &#x1f4a1; 在代码的世界里沉浸了十余载&#xff0c;我一直自诩逻辑思维敏捷&#xff0c;编程能力不俗。然而&#xff0c;当我初次接触 DeepSeek-R1 并领略其清晰、系统的思考过程时&#xff0c;我不禁为之震撼。那一刻&#xff0c;我深刻意识到&#xff1a;在A…

MySQL 实验1:Windows 环境下 MySQL5.5 安装与配置

MySQL 实验1&#xff1a;Windows 环境下 MySQL5.5 安装与配置 目录 MySQL 实验1&#xff1a;Windows 环境下 MySQL5.5 安装与配置 一、MySQL 软件的下载二、安装 MySQL三、配置 MySQL 1、配置环境变量2、安装并启动 MySQL 服务3、设置 MySQL 字符集4、为 root 用户设置登录密…

烟花燃放安全管控:智能分析网关V4烟火检测技术保障安全

一、方案背景 在中国诸多传统节日的缤纷画卷中&#xff0c;烟花盛放、烧纸祭祀承载着人们的深厚情感。一方面&#xff0c;烟花璀璨&#xff0c;是对节日欢庆氛围的热烈烘托&#xff0c;寄托着大家对美好生活的向往与期许&#xff1b;另一方面&#xff0c;袅袅青烟、点点烛光&a…

Elasticsearch:解锁深度匹配,运用Elasticsearch DSL构建闪电般的高效模糊搜索体验

目录 Elasticsearch查询分类 叶子查询 全文检索查询 match查询 multi_match查询 精确查询 term查询 range查询 复杂查询 bool查询简单应用 bool查询实现排序和分页 bool查询实现高亮 场景分析 问题思考 解决方案 search_after方案(推荐) point in time方案 方案…

数据安全VS创作自由:ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南

文章目录 数据安全VS创作自由&#xff1a;ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南ChatGPTKimi腾讯元宝DeepSeek 数据安全VS创作自由&#xff1a;ChatGPT与国产AI工具隐私管理对比——论文党程序员必看的避坑指南 产品隐私设置操作路径隐私协议ChatGPT…

FFmpeg入门:最简单的音视频播放器

FFmpeg入门&#xff1a;最简单的音视频播放器 前两章&#xff0c;我们已经了解了分别如何构建一个简单和音频播放器和视频播放器。 FFmpeg入门&#xff1a;最简单的音频播放器 FFmpeg入门&#xff1a;最简单的视频播放器 本章我们将结合上述两章的知识&#xff0c;看看如何融…

windows 上删除 node_modules

在 Windows 11 上&#xff0c;你可以通过命令行来删除 node_modules 文件夹并清除 npm 缓存。以下是具体步骤&#xff1a; 删除 node_modules 打开命令提示符&#xff08;Command Prompt&#xff09;或终端&#xff08;PowerShell&#xff09;。 导航到项目目录。你可以使用 …

kotlin的val声明的变量是常量吗

kotlin的val声明的变量是常量吗 DeepSeek R1 思考 65 秒 思考过程 嗯&#xff0c;用户问的是Kotlin中的val声明的变量是不是常量。首先我需要回忆一下Kotlin的基础知识。记得在Kotlin里&#xff0c;val用来声明只读变量&#xff0c;也就是说一旦赋值之后就不能再重新赋值了。…

Linux下学【MySQL】中如何实现:多表查询(配sql+实操图+案例巩固 通俗易懂版~)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是MySQL篇中&#xff0c;非常实用性的篇章&#xff0c;相信在实际工作中对于表的查询&#xff0c;很多时候会涉及多表的查询&#xff0c;在多表查询…

【基础4】插入排序

核心思想 插入排序是一种基于元素比较的原地排序算法&#xff0c;其核心思想是将数组分为“已排序”和“未排序”两部分&#xff0c;逐个将未排序元素插入到已排序部分的正确位置。 例如扑克牌在理牌的时候&#xff0c;一般会将大小王、2、A、花牌等按大小顺序插入到左边&…

【Flink银行反欺诈系统设计方案】3.欺诈的7种场景和架构方案、核心表设计

【Flink银行反欺诈系统设计方案】3.欺诈的7种场景和架构方案、核心表设计 1. **欺诈场景分类与案例说明**1.1 **大额交易欺诈**1.2 **异地交易欺诈**1.3 **高频交易欺诈**1.4 **异常时间交易欺诈**1.5 **账户行为异常**1.6 **设备指纹异常**1.7 **交易金额突变** 2. **普适性软…

迷你世界脚本生物接口:Creature

生物接口&#xff1a;Creature 彼得兔 更新时间: 2024-05-22 17:51:22 继承自 Actor 具体函数名及描述如下: 序号 函数名 函数描述 1 getAttr(...) 生物属性获取 2 setAttr(...) 生物属性设置 3 isAdult(...) 判断该生物是否成年 4 setOxygenNeed(…