信号和槽机制概述:
信号和槽用于两个对象之间的通信。信号和槽机制是Qt的核心特征,也是Qt不同于其他开发框架最突出特征。有时候,我们希望某个对象任何时候都可以跟其他对象通信。例如,有一个对象A,定时向B发送一个数字,对象B接收到该数字就将其打印出来。又或者有一个按钮,当用户点击该按钮时调用close()来关闭窗口。为了实现这些功能,一些工具包中使用了回调(callback)机制,而在Qt中使用信号和槽来进行对象间的通信。
简单的例子:
创建两个对象MySignal和MySlot,使用connect将两个对象关联起来,MySlot发送5次信号,MySignal将从MySlot接收到的信号分别打印出来。
mysignal.h
#ifndef MYSIGNAL_H
#define MYSIGNAL_H
#include <QObject>
class MySignal:public QObject
{
Q_OBJECT //使用这个宏才可使用信号槽
public:
MySignal();
void run();
signals:
void myslot(int a); //声明一个信号,不需要实现
private:
int a;
};
#endif // MYSIGNAL_H
mysignal.cpp
#include "mysignal.h"
MySignal::MySignal()
{
}
void MySignal::run()
{
for(int i=0;i<5;i++)
{
emit myslot(i); //发射信号
}
}
myslot.h
#ifndef MYSLOT_H
#define MYSLOT_H
#include <QObject>
class MySlot:public QObject
{
Q_OBJECT //使用这个宏才可使用信号槽
public:
MySlot();
public slots:
void coutI(int a); //声明一个槽函数
};
#endif // MYSLOT_H
myslot.cpp
#include "myslot.h"
#include <QDebug>
MySlot::MySlot()
{
}
void MySlot::coutI(int a)
{
qDebug() << "nums is" << a;
}
main.cpp
#include <QCoreApplication>
#include "mysignal.h"
#include "myslot.h"
//#include <QObject>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MySlot slo;
MySignal *sig = new MySignal;
//将信号槽进行连接
QObject::connect(sig,SIGNAL(myslot(int)),&slo,SLOT(coutI(int)));
sig->run();
return a.exec();
}
运行结果:
总结:
1)实现信号和槽的类必须包含Q_OBJECT宏
2)信号需要声明在signals保留字下,并不需要实现
3)槽声明在slots保留字下,需要实现函数
4)信号和槽通过QObject::connect函数连接
5)当信号被触发时,槽函数被调用
注意:
1)信号和槽机制是Qt的扩展,所以实现信号和槽的类必须是QObject类的子类;
2)连接信号和槽,要用到SIGNAL和SLOT两个宏将,转换函数为字符串;
3)信号声明为void类型,如void _slot()
4)一个信号可以连接多个槽,槽的调用顺序为连接的顺序;
5)多个信号可以连接一个槽;
6)信号可以连接信号,形成信号传导;
7)信号和槽的参数应该一样多,并且参数类型相同;
8)信号和槽都可以重载;
9)信号和槽可以有默认参数;
10)槽函数可以和普通函数一样被调用;
11)在槽函数中使用sender可以获得信号拥有者;
记住几个关键词:
一个类:QObject
三个宏:O_OBJECT、SIGNAL、SLOT
三个保留字:signals、slots、emit