信号与槽的介绍
1.信号和槽概述qt中谈到信号涉及到三个要素1.信号源由哪个控件发出信号。2.信号的类型用户进行不同的操作就可能触发不同的信号(点击按钮触发点击信号、在输入框中移到光标触发移到光标的信号等)。3.信号的处理方式槽(slot)其实就是一个函数qqt中使用connect这样的函数把一个信号和一个槽关联起来后续只要信号触发了qt就会自动的执行槽函数。所谓的槽函数本质是上也是一种回调函数。qt中一定是先关联信号和槽然后再触发这个信号顺序不能颠倒否则信号就不知道如何处理了。2. 信号和槽的使用qt中要想使用信号和槽离不开一个关键的函数叫connect它是QObject提供的静态的成员函数。Qt中提供的这些类本身是存在一定的继承关系的了比如QPushButton、QLineEdit等类是继承自QWidget(控件)类的QWidget再往上还有个父类是QObjectQObject就是其它qt内置类的祖宗。由于connect函数是QObject这个类提供的其它qt的类又是间接的继承自这个类所以都可以使用到connect。接下来看看connect的具体的使用方式这是connect的函数原型这个里面有5个参数最后一个是个默认参数(暂时不考虑)。第一个参数要传一个QObject指针的sender其实它就是信号源它就描述了当前信号是哪个控件发出来的。第二个参数描述了信号的种类发出的是哪一个信号。第三个和第四个参数描述的是信号如何处理第三个说的是哪个对象(控件)负责处理第四个说的是这个对象该怎么处理(要处理信号的对象提供的成员函数)。下面写代码来演示一下我们的例子是界面上有个按钮用户点击按钮关闭窗口当前有了窗口和关闭按钮只不过现在点按钮并没有任何效果。继续完善我们的所谓的信号也是qt中的对象内部提供的一些成员函数click是一个slot函数作用是在调用的时候相当于点击了一下按钮。clicked(过去分词)才是要触发的点击信号(图标上有锯代表槽函数带信号的表示信号函数)。connect要求第一个参数和第二个参数是匹配的。button的类型如果是QPushButton*此时第二个参数的信号必须是QPushButton内置的信号(它父类的信号)不能是一个其它的类比如QLineEdit的信号。继续看通过Widget来相应前面的点击信号close是QWidget内置的槽函数Widget继承自QWidget也就继承了父亲的槽函数。close槽函数功能是人家内部实现好的不需要我们去关心具体的功能是关闭当前的窗口/控件。后续针对button进行点击Widget就会关闭。下面测试可以发现点击后就关闭了。写完了代码现在还有两个问题1.怎么知道的QPushButton有个clicked信号怎么知道QWidget有个close槽Qt里到底都提供了哪些内置的信号和槽可以让我们直接使用呢多看文档在QPushButton中没有找到clicked信号。在翻阅文档的时候如果在当前类中没有找到对应的线索不妨看看这个类的父类可以看到QPushButton的父类是QAb子类是QCo。abstract是抽象的意思qt中会提供好几种按钮这些按钮之间存在一些共性内容就把这些共性的东西提取出来放到了QAbstractButton类里面按钮把共性继承再扩展自己的。点过去看看往下翻找看到了信号函数它的子类就都可以使用。点开后也有描述2.connect第二个参数和第四个参数都是char*类型的但我们填写的是函数指针那char*和函数指针是同一个东西吗它们都不是一样的类型。我们点进去看看声明所以指向这个函数的指针是void(*)()类型的指针和char*不是一个类型。那形参是char*我们传的函数指针类型c中不允许用两个不同的指针类型相互赋值这里为什么可以点开文档发现也是char*其实这个函数声明是以前旧版本的Qt的connect函数的声明以前版本中传参的写法和现在其实也是有区别的。给信号参数传参要搭配一个SIGNAL宏给槽函数传参搭配一个SLOT宏搭配宏可以把函数指针分别转为char*。以前版本这样写从Qt5开始对上述写法做了简化不需要写这两个宏了给connect提供了重载版本。重载版本中第二个参数和第四个参数成了泛型参数就允许传入任意类型的函数指针此时connect函数就带有了一定的参数检查功能如果你传入的第一个参数和第二个参数不匹配或者第三个参数和第四个参数不匹配(不匹配说的是2 4参数的函数指针不是1 3参数的成员函数)此时代码编译出错。前面的例子中给的信号是qt内置的槽也是qt内置的但有时候内置的不一定能满足我们的要求所以我们还要能自定义信号和槽。先来说说自定义槽所谓的slot就是一个普通的成员函数自定义一个槽函数操作过程和自定义一个普通的成员函数没有什么区别下面来测试一下再来说说第二种定义槽函数的方式用qt designer先拖动一个Button过去此时就能使用ui-objectName访问自动生成的控件按照第一种方式继续通过connect完成信号槽的连接是这样的但还有更容易的方式选择clicked点击发现qt creator生成了函数的声明和定义我们编写就行了下面测试一下发现第二种方式没有connect在qt中除了通过connect来连接信号槽之外还可以通过函数名字的方式来自动连接。我们看看自动生成的槽函数的名字on是固定的前缀pushButton是按钮的objectName在后面是信号的名字。通过函数名可以了解到把pushButton这个按钮它的clickde信号和当前函数建立连接。当函数名符合上述规则之后qt就能自动的把信号的槽给建立上联系。比如故意把名字后面改为qt没有的信号click试一下此时点击按钮没有任何反应。通过提示也知道qt中调用画红线的这个函数的时候就会触发上述自动连接信号槽的规则这正式在自动生成的ui_widget.h中调用的如果我们通过图形化的界面创建控件还是推荐使用第二种快速的方式来连接信号槽如果我们是通过代码的方式来创建控件还是得收到connect因为这种情况代码中没有调用connectSlotByName函数。下面来说说怎么自定义信号函数qt中也允许自定义信号。自定义函数槽非常关键开发中大部分情况都是需要自定义槽函数的槽函数就是用户触发某个操作之后要进行的业务逻辑。自定义信号比较少见实际开发中很少会需要自定义信号信号就对应到用户的某个操作在GUI中用户能够进行哪些操作是可以穷举的qt内置的信号基本上已经覆盖到了上述所有可能的用户操作。因此使用qt的内置信号就足以应付大部分的开发场景了。咱们的Widget虽然还没有定义任何信号由于继承自QWidget和QObject这两类里面已经提供了一些信号了可以直接使用。下面来看看自定义信号1.所谓的qt的信号本质上也就是一个函数。但是信号则是一类非常特殊的函数程序员只要写出函数声明并且告诉qt这是一个信号即可。这个函数的定义是qt在编译过程中自动生成的(自动生成的过程程序员无法干预)。2.作为信号函数这个函数的返回值必须是void。有没有参数都可以甚至也可以支持重载。下面简单演示一下(signals是qt自己扩展出的关键字qmake时会调用一些代码的分析/生成工具扫描到类中包含signals这个关键字的时候就会自动的把下面的函数声明认为是信号并且给这些信号函数自动的生成函数定义)此时就会把signals下面的函数声明当信号并给信号自动生成对应的函数定义。下面再把信号和槽关联起来下面测试一下没反应因为此时信号和槽建立连接不代表信号发出来了。那这个自定义的信号如何触发呢Qt内置的信号都不需要手动通过代码来触发用户在GUI进行某些操作就会自动触发对应信号(发射信号的代码已经内置到qt框架中了)。我们自定义的要自己emit(发射)定义的信号发送的信号的操作可以在任何合适的代码中不一定在构造函数里。比如这样(ui中创建按钮和信号)此时是这样一个过程其实现在qt5中emit什么都没有做真正的操作都包含在mySignal内部生成的函数定义了不加emit信号也是可以的发出去的(建议加)3.带参数的信号和槽我们前面写的信号和槽都是不带参数的信号函数和槽函数其实也是可以带参数的。当信号带有参数的时候槽的参数必须和信号参数一致。此时发射信号的时候就可以给信号函数传递实参与之对应的这个参数就会被传递到对应的槽函数中此时就可以起到让信号给槽传参的效果了。下面加个参数看看这里的参数必须一致。一致主要是要求类型个数如果不一致也可以不一致的时候要求信号的参数的个数必须要比槽的参数的个数要更多。进一步完善实现代码此时信号的实参会被传到槽函数的实参里面。下面测试一下传参可以起到复用代码的效果有多个逻辑逻辑上整体一致但是涉及到的数据不同就可以通过函数参数来复用代码并且在不同场景中传入不同的参数即可。比如多加一个按钮给第二个按钮也设置槽函数继续完善现在信号是同一个信号槽也是同一个槽但是可以通过参数达成不同的效果qt中很多内置的信号也只带有参数的这些参数不是我们自己传递的。下面再看看参数个数不一致的情况现在信号的参数多槽的参数少。继续补齐此时虽然槽函数只有一个参数但不影响程序的正常运行。测试发现正确所以信号函数的参数个数超过了槽函数的参数个数此时是可以正常使用的。下面反过来试一试下面再次去测试一下有很多报错所以信号函数的参数个数少于槽函数的参数个数此时代码无法编译通过。直观的思考应该是要求信号的参数个数和槽的参数个数严格一致此处为啥允许信号的参数比槽的参数多呢一个槽函数有可能会绑定多个信号如果我们严格要求参数个数一致就意味着信号绑定到槽的要求就变高了。换而言之当下这样的规则就允许信号和槽之间的绑定更灵活了更多的信号可以绑定到这个槽函数上了。个数不一致槽函数就会按照参数顺序拿到信号的前N个参数至少需要确保槽函数的每个参数都是有值的。要求信号给槽的参数可以有富裕但不能少。再看一下参数类型的影响下面测试一下同样编译报错。因此带有参数的信号要求信号的参数和槽的参数一致类型和个数满足要求(信号的参数个数要多于槽的参数个数)。再介绍一个和信号槽与关系的部分在widget.h中针对Widge类进行声明里面有个这样的宏Qt中如果要让某个类能够使用信号槽(可以在类中定义信号和槽)则必须要在类最开始的地方写下Q_OBJECT宏这是Qt中的硬性规定。如果不加这个宏这个类在编译的时候也会出错。4.信号与槽的断开我们可以使用disconnect来断开信号槽的连接disconnect使用的方式和connect是非常类似的。disconnect用的比较少大部分情况下把信号和槽连上后就不必管了主动断开往往是把信号重新绑定到另一个槽函数上。下面演示一下先拖动一个按钮继续完善此时点击按钮窗口标题发生改变然后再用另一个按钮切换槽函数然后来完善下面演示此时点第一个按钮标题改变再点第二个按钮后再点第一个标题又改变。如果没有disconnect就会构成一个信号绑定两个槽函数触发信号的时候两个槽函数都会执行。5.使用lambda表达式定义槽函数定义槽函数的时候也是可以使用lambda表达式的。很多编程语言都支持这个语法糖它本质就是一个匿名函数主要应用在回调函数的场景中。下面结合代码看一下效果下面运行一下说明槽函数可以顺利执行了。现在我想点击按钮的时候把按钮的位置移动一下怎么办呢发现此时用的时候说button按钮没有定义。因为lambda表达式是一个回调函数这个函数无法直接获取到上层作用域中的变量的。当前button定义是在9~20这个作用域而lambda是自成一个体系获取不到外面的变量。lambda为了解决上述问题引入“变量捕获”语法通过变量捕获获取到外层作用域中的变量在方括号中下手此时相当于让lambda表达式能够把外层作用域中的button变量名捕获到lambda表达式里面这时候就可以在lambda表达式里面使用了类似的比如想在lambda表达式里面对this进行操作就可以捕获一个this比如移动一下窗口此时运行可以看到按钮和窗口位置都会发生移动。如果当前lambda里面想使用更多的外层变量咋办可以写作[]这个写法的含义就是把上层作用域中所有的变量名都给捕获进来后续如果我们对应的槽函数比较简单而且是一次性使用的就会经常写作这种lambda的形式。另外也要确认捕获到lambda内部的变量是有意义的回调函数执行时机是不确定的(用户啥时候点击按钮不知道的)无论何时用户点击了按钮捕获到的变量都能正确使用(不要用的时候已经被释放了)。由于此处button是new出来的变量生命周期跟随整个窗口(挂到对象树上窗口关闭才会释放)这个东西就可以在后面随时使用了。类似的this指向的对象widget这个变量是在main函数结束销毁main函数结束说明进程结束了只要进程不结束widget就可用this也就可用了。lambda除了可以按照值的方式来捕获变量[]还可以按照引用的方式来捕获[]但很少这样写捕获到的变量一般就是各种控件的指针。指针变量按照值传递或者引用来传递都无所谓如果按引用还得更关注这个引用的变量本身的生命周期。lambda语法是c11中引用的对于Qt5及其更高版本默认就是按照c11来编译的。如果使用Qt4或者更老的版本就需要手动在.pro文件中加上c11的编译选项

相关新闻

settings.local.json,Claude Code 里最适合个人差异化配置的一层

settings.local.json,Claude Code 里最适合个人差异化配置的一层

最近在梳理 Claude Code 的配置体系时,最容易被低估的文件之一就是 .claude/settings.local.json。它不像 CLAUDE.md 那样负责给模型提供项目背景,也不像 .claude/settings.json 那样适合提交到仓库、统一团队行为。它更像一个贴在本机开发环境旁边的小控制台,专门处理个人偏…

2026/7/21 23:37:10阅读更多 →
海洋观测技术:从传统探测到空天地海一体化

海洋观测技术:从传统探测到空天地海一体化

1. 海洋观测技术发展现状与突破我国海洋观测技术近年来取得了一系列重大突破,从传统的水下探测发展到空天地海一体化观测体系。这种技术飞跃主要体现在三个方面:首先是观测范围的扩展。传统海洋观测主要依靠船舶和浮标等水面设备,观测深度和范…

2026/7/21 23:37:10阅读更多 →
社交平台 AI 功能的用户接受度:推荐算法透明性,决定信任成败的关键

社交平台 AI 功能的用户接受度:推荐算法透明性,决定信任成败的关键

社交平台 AI 功能的用户接受度:推荐算法透明性,决定信任成败的关键 一、"这个推荐是怎么来的?""因为这个功能就是为了让你花更多时间在平台上" 这是社交平台用户对 AI 推荐最常见的两种态度。一部分用户接受推荐并乐在其…

2026/7/21 23:37:10阅读更多 →
深入解析eQEP模块:从正交编码器原理到高精度位置速度测量实践

深入解析eQEP模块:从正交编码器原理到高精度位置速度测量实践

1. 项目概述与核心价值在伺服电机、机器人关节、数控机床这类需要精确控制旋转或直线位移的嵌入式系统中,如何实时、准确地获取执行机构的位置和速度,是决定整个系统性能上限的关键。这就像给一个盲人装上眼睛,他才能知道自己在哪&#xff0c…

2026/7/22 1:53:59阅读更多 →
Windows下C/C++连接MySQL数据库实战指南

Windows下C/C++连接MySQL数据库实战指南

1. Windows环境下C/C连接MySQL数据库的核心思路在Windows平台上用C/C连接MySQL数据库,本质上是通过MySQL提供的C API与数据库服务建立通信通道。这个过程涉及到几个关键组件:MySQL客户端库(libmysql.dll)、头文件(mysq…

2026/7/22 1:53:59阅读更多 →
大学生学 AI,第一步应该学什么?

大学生学 AI,第一步应该学什么?

当下人工智能已经渗透校园学习、实习求职、专业创作全场景,中国青年报社面向 1032 名大学生的调研显示,99.2% 的在校生日常使用 AI 工具,但 29.84% 的学生仅会基础对话,缺乏系统学习路径,只会用 AI 应付作业&#xff0…

2026/7/22 1:53:59阅读更多 →
USB Fuzzer — 基于 Raspberry Pi Zero 2 W 的便携式 USB 协议 Fuzzing 与设备模拟工具(开源 · 网页操控)

USB Fuzzer — 基于 Raspberry Pi Zero 2 W 的便携式 USB 协议 Fuzzing 与设备模拟工具(开源 · 网页操控)

[AI 整理声明] 本文基于作者的项目文档与开发实践,由 AI 辅助整理输出,核心内容与数据均来自作者本人。 目录硬件部署设备模拟USB Fuzz日志系统信息架构注意USB 是整机设备的通用外设入口,主机侧的 USB 协议栈(枚举、描述符解析、…

2026/7/22 1:53:59阅读更多 →
C# 11新特性解析与应用实践

C# 11新特性解析与应用实践

1. C# 11新特性全景概览C# 11作为微软2022年推出的重要版本更新,带来了诸多令人振奋的语言增强。这些新特性并非简单的语法糖,而是从编译器层面进行的根本性改进,显著提升了开发效率、代码安全性和表达力。根据我在实际项目中的使用体验&…

2026/7/22 1:53:59阅读更多 →
深入解析C2000 Bootloader数据流与多模式引导实现

深入解析C2000 Bootloader数据流与多模式引导实现

1. 项目概述与核心价值在嵌入式系统开发中,我们常常会面对一个看似简单却至关重要的环节:系统如何从“一片空白”的状态,加载并运行我们精心编写的应用程序?这个问题的答案,就是引导加载程序,也就是我们常说…

2026/7/22 1:51:59阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

2026/7/22 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/21 18:53:30阅读更多 →