一.信号和槽概述
信号与槽(Signal & Slot)是 Qt 编程的基础,也是 Qt 的一大创新。因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。
信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号。发射信号使用Qt的emit关键字。定义信号使用QT的signals关键字。
槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以声明在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
注:
(1)信号和槽机制底层是通过函数间的相互调⽤实现的。每个信号都可以⽤函数来表⽰,称为信号函 数;每个槽也可以⽤函数表⽰,称为槽函数。例如:"按钮被按下"这个信号可以⽤clicked()函数表 ⽰,"窗⼝关闭"这个槽可以⽤close()函数表⽰。
eg:使⽤信号和槽机制- 实现:"点击按钮会关闭窗⼝"的功能,其实就是按钮发出clicked信号,窗口做出close函数回应,即clicked()函数调⽤close()函数的效果。
(2)信号函数只需要声明,不需要定义(实现),⽽槽函数需要定义(实现)。
二. 信号和槽的使⽤
1 .连接信号和槽 --- connect函数
在Qt中,QObject类提供了⼀个静态成员函数connect(),该函数专⻔⽤来关联指定的信号函数和槽 函数。
connect()函数原型:
cpp
connect (
const QObject *sender,
const char* signal,
const QObject* receiver,
const char* method,
QT::ConnectionType type =QT::AutoConnection)
参数说明:
• sender:信号的发送者;
• signal:发送的信号类型(信号函数);
• receiver:信号的接收者;
• method:接收信号的槽函数;
• type:⽤于指定关联⽅式,默认的关联⽅式为Qt::AutoConnection,通常不需要⼿动设定。
eg:在窗⼝中设置⼀个按钮,当点击"按钮"时关闭"窗⼝"
2. 查看内置信号和槽
系统⾃带的信号和槽通常是通过"Qt帮助⽂档"来查询。 如上述⽰例,要查询"按钮"的信号,在帮助⽂档中输⼊:QPushButton,
• ⾸先可以在"Contents"中寻找关键字signals,
• 如果没有找到,继续去⽗类中查找.因此我们去他的⽗类QAbstractButton中继续查找关键字 signals,
3. 通过QtCreator⽣成信号槽代码
Qt Creator可以快速帮助我们⽣成信号槽相关的代码.
eg:在窗⼝中设置⼀个按钮,当点击"按钮"时关闭"窗⼝"
(1)、新建项⽬,如下图为新建完成之后所包含的所有⽂件;
(2)、双击widget.ui⽂件,进⼊UI设计界⾯;
(3)、在UI设计窗⼝中拖⼊⼀个"按钮",并且修改"按钮"的名称及字体⼤⼩等;
(4)、可视化⽣成槽函数;
当单击 "转到槽..." 之后,出现如下界⾯:对于按钮来说,当点击时发送的信号是:clicked(),所以此 处选择:clicked()
(5)、⾃动⽣成槽函数原型框架;
①在"widget.h"头⽂件中⾃动生成槽函数的声明;
②在"widget.cpp"中⾃动⽣成槽函数定义.
(6)、在槽函数函数定义中添加要实现的功能. 实现关闭窗⼝的效果.
结果:
三. ⾃定义信号和槽
1. 基本语法
在Qt中,允许⾃定义信号的发送⽅以及接收⽅,即可以⾃定义信号函数和槽函数。但是对于⾃定义的 信号函数和槽函数有⼀定的书写规范。
1.1.⾃定义信号函数书写规范
(1)⾃定义信号函数必须写到"signals"下;
(2)返回值为void,只需要声明,不需要实现;
(3)可以有参数,也可以发⽣重载;
1.2.⾃定义槽函数书写规范
(1)早期的Qt版本要求槽函数必须写到"public slots"下,但是现在⾼级版本的Qt允许写到类 的 "public"作⽤域中或者全局下;
(2)返回值为void,需要声明,也需要实现;
(3)可以有参数,可以发⽣重载
eg:1、在widget.h中声明⾃定义的信号和槽,如图所⽰:
在widget.cpp中实现槽函数,并且关联信号和槽:
结果:
2.带参数的信号和槽
Qt的信号和槽也⽀持带有参数,同时也可以⽀持重载.
此处我们要求,信号函数的参数列表要和对应连接的槽函数参数列表⼀致. 此时信号触发,调⽤到槽函数的时候,信号函数中的实参就能够被传递到槽函数的形参当中.
这样的机制,可以实现信号函数向槽函数传递数据
eg:重载信号槽
1)在"widget.h"头⽂件中声明重载的信号函数以及重载的槽函数;如下图所⽰:
(2)在"Widget.cpp"⽂件实现重载槽函数以及连接信号和槽。
注意:在定义函数指针时要指明函数指针的作⽤域。
执⾏结果如下图所⽰:
四. 信号与槽的连接⽅式
1.一对一
一对一主要有两种形式:一个信号对应一个槽,一个信号对应一个信号
1.1.一个信号对应一个槽函数
eg:
在"widget.h"中写出声明
在"widget.cpp"中实现槽函数,信号发射函数以及连接信号和槽
1.2.一个信号对应一个信号
eg:在上述⽰例的基础上,在"widget.cpp"⽂件中添加如下代码:
2.一对多
一个信号连接多个槽函数
eg:
(1)在"widget.h"头⽂件中声明⼀个信号和三个槽;
(2)在"widget.cpp"⽂件中实现槽函数以及连接信号和槽;
3.多对一
多个信号对应一个槽函数
⽰例: (1)在"widget.h"头⽂件中声明多个信号和一个槽;
(2)在"widget.cpp"⽂件中实现槽函数以及连接信号和槽;
五.信号与槽的断开
使用disconnect断开连接即可。
disconnect用法与connect一致
eg: