信号和槽(Signal & Slot)用于两个对象(object)进行交流,通俗地来说,就是一个对象发出什么信号,另一个对象执行相应的动作(比如跑步比赛中,裁判员发出枪响信号,运动员开始起跑)。
信号(Signal):相当于发出一个事件通知。
槽(Slot):槽其实是一个函数,为了响应信号而执行的一系列的指令。
连接(connect):这个连接的过程,就是,我们指定什么样的信号执行什么样的槽函数。
Qt里只有从QOBject派生来的类,才支持信号与槽。主要分为两类:1、Qt类自带的;2、用户自定义的。
对于Qt中自带的信号而言,一般只需要知道有哪些信号,直接去使用即可,Qt中常见的几个信号如下:
void clicked(bool checked = false)
void pressed()
void released()
void toggled(bool check)
如果想要使用自定义的信号, 首先要编写新的类并且让其继承Qt的某些标准类,我们自己编写的类想要在Qt中使用使用信号槽机制, 那么必须要满足的如下条件:
1. 这个类必须从QObject类或者是其子类进行派生
2. 在定义类的头文件中加入 Q_OBJECT 宏
要求:
1. 信号是类的成员函数
2. 返回值是 void 类型
3. 信号的名字可以根据实际情况进行指定
4. 参数可以随意指定, 信号也支持重载 void signal_test(int, int, char);
5. 信号需要使用 signals 关键字进行声明, 使用方法类似于public等关键字
6. 信号函数只需要声明
7. 在程序中发送自定义信号: 发送信号的本质就是调用信号函数
当我们写下一下emit signal代码的时候,与这个signal相连接的slot就会被调用,那么这个调用是如何发生的呢?让我们来逐一解开其中的谜团。
来看一段例子代码:
class ZMytestObj : public QObject
{
Q_OBJECT
signals:
void sigMenuClicked();
void sigBtnClicked();
};
编译器在做完预处理之后的代码如下:
// SIGNAL 0
void ZMytestObj::sigMenuClicked()
{
QMetaObject::activate(this, &staticMetaObject, 0, 0);
}
// SIGNAL 1
void ZMytestObj::sigBtnClicked()
{
QMetaObject::activate(this, &staticMetaObject, 1, 0);
所以信号函数也可以自己写成这样的方式去定义。
特点为:
1.返回值void
2.参数可以有,参数的类型和个数需要和对应的信号对应起来,参数个数可以比信号少,但不能多void slot_test(int);与前面的void signal_test(int, int, char)对应
connect函数
//QT4
connect(m_pPushBtn, SIGNAL(clicked(bool)), &signalTest, SLOT(slots_TestSlot1()));
//QT5
connect(m_pPushBtn, &QPushButton::clicked, &signalTest, &CSignalTest::slots_TestSlot1);
注意:
1.一个信号可以连接到多个槽函数
信号触发之后,所有槽函数都被调用,调用顺序不确定
2.一个槽函数,可以被多个信号连接
其中某一个信号触发时,槽函数都将被调用
3.connect可以连接信号与信号
connect(m_pPushBtn, SIGNAL(clicked(bool)), &signalTest, SIGNAL(signals_TestSignls()));