基本概念
信号与槽(Signal & Slot)是 Qt 编程的基础,也是 Qt 的一大创新。因为有了信号与槽的编程机制,在 Qt 中处理界面各个组件的交互操作时变得更加直观和简单。
信号(Signal)就是在特定情况下被发射的事件,例如PushButton 最常见的信号就是鼠标单击时发射的 clicked() 信号,一个 ComboBox 最常见的信号是选择的列表项变化时发射的 CurrentIndexChanged() 信号。槽(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以定义在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用。槽函数与一般的函数不同的是:槽函数可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行。
信号与槽关联是用 QObject::connect() 函数实现的,其基本格式是:
QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
信号连接槽主要的特性:
1:一个信号可以对应多个槽;多个信号可以对应一个槽。
2:一个信号可以连接另一个信号。
3:信号与槽的参数个数和类型需要一致,至少信号的参数不能少于槽的参数。
4:当一个信号被发射时,与其关联的槽函数通常被立即执行,就像正常调用一个函数一样。只有当信号关联的所有槽函数执行完毕后,才会执行发射信号处后面的代码。
代码案例
假设有这样一个场景:
有两个类:妈妈类和儿子类;
妈妈类中有1个信号:做饭时间;有一个动作:回家做饭。
儿子类中有1个信号:放学回家;有一个动作:打扫教室。案例代码如下:
#include <QObject> #include <QDebug> // 妈妈类 class mom: public QObject { Q_OBJECT public: explicit mom(QObject *parent = nullptr); signals: void cookTime(); // 中午做饭时间到了 public slots: void cook(){ qDebug() << "---回家做饭---" ;} }; // 儿子类 class son: public QObject { Q_OBJECT public: explicit son(QObject *parent = nullptr); signals: void goHome(); // 放学时间到了 public slots: void cloosDoor(){ qDebug() << "---打扫教室卫生---" ; } }; …… mom *pMom = new mom(); son *pSon = new son(); // 一个信号可以对应两个槽 // 儿子放学信号后妈妈回家做饭 connect(pSon , &son::goHome, pMom, &mom::cook); // 儿子放学信号后打扫教室卫生 connect(pSon , &son::goHome, pSon , &son::cloosDoor); // 信号可以连接信号 // 中午做饭时间到了,妈妈回家做饭 connect(pMom, &mom::cookTime, pMom, &mom::cook); // 儿子放学的信号连接妈妈类中的中午做饭时间信号 connect(pSon , &son::goHome, pMom, &mom::cookTime); ……
Qt中的槽函数实现在新版本的C++11里可以借助Lambda表达式,Lambda表达式简单格式为:[ ]( ){ }。[ ]:表示符,( ):参数,{ }:实现体;运用Lambda表达式可以使得槽函数的实现更加丰富多样性。