目录
关于信号
关于信号在 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 函数就带有了一定的 参数检査 功能