使用connect()可以让我们连接系统提供的信号和槽,同时也可以自定义信号槽。
例如以学生和老师构建类同时当老师触发信号下课同学收到信号执行“吃饭”这一动作代码示例
#include "SignalAndSlot.h"
//Teacher Student 总框架类用以实现自定义信号槽
SignalAndSlot::SignalAndSlot(QWidget *parent): QWidget(parent)
{ui.setupUi(this);this->zt = new Teacher(this);this->st = new Student(this);connect(this->zt, &Teacher::Hungry, this->st, &Student::treat);classover();
}SignalAndSlot::~SignalAndSlot()
{}void SignalAndSlot::classover()
{//触发自定义的信号emit this->zt->Hungry();}
#pragma once#include <QObject> //老师类class Teacher : public QObject
{Q_OBJECTpublic:Teacher(QObject* parent = 0);~Teacher();
signals: //自定义信号 写到signala下//1.返回值类型是void//2.只需要声明,不需要实现//3.可以有参数,可以发生重哉void Hungry();
};
#pragma once#include <QObject> //学生类class Student : public QObject
{Q_OBJECTpublic:Student(QObject* parent = 0);~Student();public slots://槽函数 写到public slots下,或者public,或者全局函数,或者lambda//返回值 void//需要声明 需要实现//可以有参数 可以重载void treat();
};
解释:
1.只有继承了QObject类的类,才具有信号槽的能力。为了使用信号槽,必须继承QObject。凡是QObject类(不管是直接子类还是间接子类),都应该在第一行代码写上Q_OBJECT。不管是不是使用信号槽,都应该添加这个宏。这个宏的展开将为我们的类提供信号槽机制、国际化机制以及 Qt 提供的不基于 C++ RTTI 的反射能力。
2.信号就是一个个的函数名,返回值是 void(因为无法获得信号的返回值,所以也就无需返回任何值),参数是该类需要让外界知道的数据。信号作为函数名,不需要在 cpp 函数中添加任何实现。
3.emit 是 Qt 对 C++ 的扩展,是一个关键字(其实也是一个宏)。emit 的含义是发出,也就是发出Hungry()信号,感兴趣的接收者会关注这个信号。
注意点:
发送者和接收者都需要是QObject的子类(当然,槽函数是全局函数、Lambda 表达式等无需接收者的时候除外);
使用 signals 标记信号函数,信号是一个函数声明,返回 void,不需要实现函数代码;
槽函数是普通的成员函数,作为成员函数,会受到 public、private、protected 的影响;
使用 emit 在恰当的位置发送信号;
使用QObject::connect()函数连接信号和槽。
任何成员函数、static 函数、全局函数和 Lambda 表达式都可以作为槽函数