介绍
原因
首先,我们假定有两个对象,来自不同类的实现,它们内部有着自己的属性,可以使用自己的成员函数来操作属性,这本身没有什么问题。
但是,在某些情景下,我们需要在一个对象中做一些操作,使得另一个对象能够响应这样的操作完成其自身状态的改变。
那么,我们如何使两个不相干的对象产生这种联系,就引出了信号与槽这样一个信息传输机制。
理解
简单理解,就是某个事件的发生,产生一个广播的信号,连接到需要该信号来完成某些操作的一个函数上。这样的函数被称作槽(slot)。槽已收到连接的信号就会被调用执行。
本质上,槽就是类的成员函数,其参数可以是任意类型的。和普通C++成员函数几乎没有区别,它可以是虚函数;也可以被重载;可以是公有的、保护的、私有的、也可以被其他C++成员函数调用。
使用方法
标准信号槽的使用
为了建立联系,需要用到connect函数,其一般形式如下:
connect(sender, signal, receiver, slot);
参数很简单,分别是信号发出者,发出的信号,信号接收者,处理信号的槽
格式:
connect(信号发出者对象(指针), &className::clicked, 信号接收者对象(指针), &classB::slot);
典型的使用方式如下:
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButton button("Quit");
// 按钮按下,窗口关闭
QObject::connect(&button, &QPushButton::clicked,&app, &QApplication::quit);
button.show();
return app.exec();
}
自定义信号槽的使用
信号和槽除了运用系统提供的,还可以自行设计
需要注意的:
类需要继承自QObject类才有信号槽的能力
信号:
- 写到signals下
- 返回值为void类型
- 需要声明,但不需要实现
- 可以有参数,可以重载
在类中声明:
signals: void function(const QString &name);
发出信号:
emit function(m_name);
槽函数:
- 返回值为void类型
- 需要声明,也需要实现
- 可以有参数,可以重载
- public slot下或者public下或者全局函数,推荐public
slot
任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数
槽函数示例
void receive(const QString & name)
{
qDebug() << "Receives Newspaper: " << name;
}
定义好如上部分后,先做连接connect,再在合适的地方激发信号emit
QObject::connect(&newspaper, &Newspaper::newPaper,
&reader, &Reader::receiveNewspaper);
newspaper.send();
使用方法扩展
- 信号与槽的连接可以一对多,多对一
- 信号可以连接另外一个信号
- 槽可以被取消连接,disconnect
- Lambda表达式的运用