Qt:信号和槽

目录

关于信号

connect函数

关于connect

connect的使用

自定义信号、自定义槽

自定义槽

第一种方式自定义槽

第二种方式自定义槽

自定义信号

信号槽

带参数的信号槽

参数个数一致的示例

参数个数不一致的示例

Q_OBJECT

信号和槽存在的意义

disconnect函数

使用lambda表达式定义槽函数


关于信号

关于信号在 Linux 中也学过信号的概念,Qt中的信号与 Linux 中的信号是不同的概念,但是也是有相似之处的

Qt 中,谈到信号,也是涉及到三个要素:

①信号源
由哪个控件发出的信号

②信号的类型
用户进行不同的操作,就可能触发不同的信号,例如:
点击按钮,触发点击信号
在输入框中移动光标,触发移动光标的信号
勾选一个复选框、选择一个下拉框都会触发出不同的信号

③信号的处理方式
槽(slot) => 函数
Qt 中可以使用 connect 这样的函数,把 一个信号和一个槽 关联起来,后续只要信号触发了,Qt 就会自动的执行槽函数

所谓的"槽函数"本质上也是一种"回调函数"(callback)

Qt 中一定是先关联好 信号和槽,然后再触发这个信号,顺序不能颠倒,否则信号就不知道如何处理了


connect函数

这个函数和 Linux TCP socket 中建立连接的函数,没有任何关系,只是名字恰巧一样

关于connect

connect函数是 QObject 提供的静态的成员函数,Qt 中提供的这些类,本身是存在一定的继承关系的:

QObject 就是其他 Qt 内置类的 祖宗

正是因为 connect函数 是 QObject 提供的,而其他的类都是继承自 QObject 的,所以其他的类也可以使用 connect函数


connect的使用

connect函数的声明:

connect (const QObject *sender, 
 const char * signal ,
 const QObject * receiver , 
 const char * method , 
 Qt::ConnectionType type = Qt::AutoConnection )

上述的 connect函数 总共有5个参数,但是第5个参数提供了一个默认参数,所以我们可以暂时不考虑,大部分情况下使用的前面4个参数

  • 参数1 sender:描述了当前信号是哪个控件发出来的

  • 参数2 signal:发送的信号类型

  • 参数3 receiver:哪个对象(控件)负责处理这个信号

  • 参数4 method:这个对象怎么处理(要处理信号的对象提供的成员函数,槽函数)


下面是简单的示例,界面上包含一个按钮,用户点击按钮,则关闭窗口:在使用QPushButton时,传入第二个参数时,有两个提示,一个是click,另一个是 clicked
click:是一个 slot 函数,作用就是在调用的时候相当于点击了一下按钮
clicked:是过去分词形式,表示点完了才会触发点击信号

我们使用的是clicked,表示点击按钮再触发点击信号

connect 要求,第一个和第二个参数是匹配的,button 的类型如果是 QPushButton*
那么第二个参数的信号必须是 QPushButton 内置的信号(或是QPushButton 父类的信号),不能是一个其他的类,比如 QLineEdit 的信号

close 是 QWidget 内置的槽函数,Widget 继承自 QWidget,也就继承了父亲的槽函数
close 槽函数功能已经是人家内部实现好了,不需要咱们去关心
close 槽函数具体的作用就是:关闭当前的窗口/控件

widget.cpp实现如下:

此时运行项目:

此时点击这个按钮就会关闭窗口了

我们是怎么得知QPushButton中有clicked函数,Widget中有close函数的?
很简单,查看文档即可,如果在当前类中没有找到,那就在当前类的父类中寻找


还有一个问题,下面是我们在代码中使用的connect函数:

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

但是我们看connect的函数声明中,前4个参数的类型如下:

connect (const QObject *sender, 
 const char * signal ,
 const QObject * receiver , 
 const char * method )

其中第一个和第三个类型是 QObject* 的,我们传入的 button 和 this 都是 QObject 的子类的指针,能够理解

但是第二个和第四个参数,声明中是 char* 的,但是我们传入的是 &QPushButton::clicked 和  &Widget::close,这两个是函数指针,并不是 char* 类型,这是为什么呢?

其实这个函数声明,是以前版本的 Qt 的 connect 函数的声明,以前版本中,传参的写法和现在其实也是有区别的,以前的版本中:
给信号参数传参时,要搭配一个 SIGNAL 宏
给槽参数传参,搭配一个 SLOT 宏,也就是下面的这种形式:

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

从 Qt 5 开始,对上述写法做出了简化,不再需要写 SIGNAL 和 SLOT 宏了
给 connect 提供了重载版本,重载版本中,第二个参数和第四个参数成了 泛型参数,允许传入任意类型的函数指针

此时 connect 函数就带有了一定的 参数检査 功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值