目录
信号的概念
Qt中的信号三要素
connect函数
connect的原型
connect的使用
信号函数和槽函数
参数匹配
close关闭槽函数
运行结果
第一个问题:怎么知道
手册使用
第二个问题,为什么可以直接传递函数指针
自定义槽函数
第一种自定义槽函数纯代码
widget.cpp
widget.h
运行结果
第二种自定义槽函数图形化操作
自定义信号
emit关键字
带参数的信号槽
widget.h
widget.cpp
带参的用处
参数个数的影响
参数类型的影响
Q_OBJECT宏
信号和槽存在的意义
实际运用
信号和槽断开连接
disconnect()
使用lambda表达式定义槽函数
版本低要手动添加C++11的编译选项
信号槽小结
信号的概念
这一点和Linux的信号有相似的地方,当然了这个不完全相同
关于信号我们也在很多地方都见到过了
Qt中的信号三要素
这个我们在之前的文章中已经见到过了
关于的触发先后的问题上,我们得小心了,一定得先有处理方式,这样接收信号的时候就不会错过了
connect函数
这个函数十分重要,首先我们得知道connect从哪里来的,在Qt中它是属于QObject这个类里面的静态成员函数,并且在Qt中所有的控件都是继承自QObject这个类的,自然我们用的QWidget可以用connect这个函数了
我们也可以看到这个继承
connect的原型
connect的使用
老样子,我们创建一个新的项目
我们创建一个按钮,用户点击之后,这个窗口就会关闭
如同我们先把这个按钮创建出来,运行发现没有什么问题,可以点击,当然了是没有反应的
信号函数和槽函数
这一点我们也需要明白,信号函数和槽函数之间的区别和关系
参数匹配
connect要求参数前两个参数要匹配
close关闭槽函数
运行结果
当我们点击这个关闭的时候,这个窗口就会关闭了
第一个问题:怎么知道
手册使用
要多看文档
这里用手册来看看这个信号和槽到底是如何知道它存在呢,我们打开手册
索引找到 QPushButton
没找到,就找它的父类
我们从它的父类中找到了clicked()这个信号函数,里面的参数我们留到后序再谈,这里我们看到,下面还有两个信号函数哦,pressed()和released(),其实一个clicked()就是一个pressed()和released()
点击进去就可以看到关于clicked的说明了
clicked函数的介绍,关于它的简介也很容易看懂
第二个问题,为什么可以直接传递函数指针
connect重载了,并且使用了泛型编程
我们可以直接跳转过去看到函数现在的声明
泛型编程
自定义槽函数
第一种自定义槽函数纯代码
我们新建一个项目
widget.cpp
写定义
widget.h
头文件写声明
public slots:这种写法已经过时了
运行结果
第二种自定义槽函数图形化操作
创建一个新的项目,并且拖拽出一个按钮
回到cpp文件,之前我们提到过,可以直接用代码的方式进行连接,但是有一种更方便的方式可以关联这个
回到UI界面,对你想要关联的控件进行右键看到这个“转到槽”,进去
我们发现里面有很多选项,这里就会是目前全部可以关联到的信号函数
我们选择clicked(),完成相应的函数,就会发现直接可以实现上面代码所实现的情况了
我们发现这个有个很奇怪的函数自动生成,这是因为Qt还可以通过函数名字来自动连接
当然了假如你更改了它的名字,就会出现报错,这是因为下面这个继承的函数名规定了规则
所以总的来说,怎么方便怎么来,显然第二种方式更方便
自定义信号
我们创建一个新的项目
我们得明白信号是一类非常特殊的函数
写个信号函数的定义,再写一个槽函数的定义
实现后运行,这里不会运行出我们想要的结果,这是因为虽然我们关联了,但是这个信号怎么触发我们并没有设置,也就是说后面的槽函数根本就触发不了
建立连接,不代表信号发出来了
如何触发自定义的信号
emit关键字
这个是Qt自己创建的一个关键字,可以用来触发信号,如下
那么如何合理的利用这个来触发信号呢?怎么用它来和用户建立连接,这里我们就通过点击这个按钮进行关联
将其写入PushButton中的槽函数中去,实现了关联
我们把emit屏蔽掉,其实也能够正常运行,不过建议加上更好一点,可读性高
带参数的信号槽
信号和槽可以带参数
widget.h
widget.cpp
运行结果,发送参数的确得到了传递
带参的用处
至于为什么要带参呢,其实这也是为了代码的复用
复用,这里我们就创建两个PushButton按钮
如图我们就有了两个按钮了
还有一定要补充的是,Qt内置了很多的信号,其中也有带参的,相信各位在操作中也看到了
参数个数的影响
信号多一个参数,槽函数还是只有一个函数
发现可以正常运行
我们反过来,就会发现一堆错误,这是因为信号的参数可以多于槽函数,但是反过来却不行
打个比方
参数类型的影响
Q_OBJECT宏
这个宏不能缺少
信号和槽存在的意义
这是比较笼统的说法
实际使用的过程中其他的GUI开发框架相比起来会更加简洁
总结来说就是其他的开发框架不需要一个connect进行连接
Qt使用connect的原因,想法很好,现实很残酷
这一套和Mysql的理念有点像
Mysql中的多对多情况
实际运用
创建一个新的项目,定义三个信号和三个槽函数
在去实现它们,如图就是这么一种情况,Qt是可以实现多对多这个操作的
Qt中的多对多
理想很好,但是现实很残酷
信号和槽断开连接
我们新建一个项目,写出一个点击就修改窗口标题的项目,这个东西我们在上面写过很多次了,就不再赘述了
我们再创建一个按钮
disconnect()
如下我们使用了disconnect(),这个函数可以帮助我们断开原来的信号
我们使用qDebug()可以更好的观察这个过程,我们看终端就可以发现,的确是切换了槽函数了
如下,就会实现一对多的情况了
使用lambda表达式定义槽函数
在Qt中我们也能够使用lambda表达式来实现槽函数
不过有一点是由于是一次性的函数,lambda表达式是无法直接获取到上层的变量
要想获取到上层的变量,我们只能够捕获它们,如下我们就能够实现点击一下就会把按钮位置换掉的程序了
再捕获一下this
如果我们想要捕获上层的所有变量,我们可以使用 =
lambda捕获参数、
确保捕获的变量是有意义的
通常我们是用值传递的,引用少一点
如下我们这里引用捕获就会出现问题 ,因为这个变量是在构造函数中的,出了函数就会自动销毁
版本低要手动添加C++11的编译选项
具体在.pro文件中添加C++11的编译选项
信号槽小结