信号与槽介绍
Qt的核心机制的信号和槽,它是是用于对象之间的通信,学Qt必须掌握信号与槽机制原理。如果你了解MFC,你就会知道Qt中的信号与槽和mfc中的消息响应机制类似。
信号槽也是 Qt 框架引以为豪的机制之一。其实信号槽类似于设计模式中的观察者模式。当某个事件发生之后,比如,按钮检测到自己被点击了一下,它就会发出一个信号(signal)。这种发出是没有目的的,类似广播。如果有对象对这个信号感兴趣,它就会使用连接(connect)函数,意思是,将想要处理的信号和自己的一个函数(称为槽(slot))绑定来处理这个信号。也就是说,当信号发出时,被连接的槽函数会自动被回调。
自定义信号与槽
信号与槽一般形式:
connect(sender,signal,receiver,slot);
sender参数是发出信号的对象,signal参数是发生对象发出的信号,receiver参数是接收信号的对象,slot参数是接收对象在接收到信号之后所需要调用的槽函数。
也就是说sender发出signal信号之后,会自动调用receiver的slot函数。
为了使用信号与槽必须继承QObject类
凡是QObject类(不管是直接子类还是间接子类)都应该在第一行代码上写上Q_OBJECT(放在头文件里)
例如:
class reader:public QObject
{
Q_OBJECT
.......
}
实现简单的信号与槽
首先定义一个A类和B类:
B类中声明信号饿了hungry
signals:
void hungury();
A类中声明槽函数请客treat
public slots:
void treat();
在窗口中声明一个公共方法,emit发送信号,这个方法的调用会触发B饿了这个信号,而响应槽函数A请客
void MyWidget::ClassIsOver()
{
//发送信号
emit b->hungury();
}
A响应了槽函数,并且打印信息
//自定义槽函数 实现
void A::eat()
{
qDebug() << "该吃饭了!";
}
在窗口中连接信号槽
b = new B(this);
a = new A(this);
connect(b,&B::hungury,a,&A::treat);
并且调用函数,测试打印出 “该吃饭了”
自定义的信号 hungry带参数,需要提供重载的自定义信号和 自定义槽
void hungury(QString name);//自定义信号
void treat(QString name );//自定义槽
但是由于有两个重名的自定义信号和自定义的槽,直接连接会报错,所以需要利用函数指针来指向函数地址, 然后在做连接
void (B:: * bSingal)(QString) = &B::hungury;
void (A:: * aSlot)(QString) = &A::treat;
connect(b,bSingal,a,aSlot);
自定义信号与槽注意事项:
- 发送者和接受者都需要是QObject的子类(当然槽函数是全局函数、lambda表达式等无需接收者的时候除外)
- 使用signal标记信号函数,信号是一个函数声明,返回void,不需要实现函数代码。
- 槽函数是普通的成员函数,作为成员函数,会受到public、private、protevted的影响。
- 使用emit在恰当的位置发送信号。
- 使用QObject::connect()函数连接信号和槽。
- 在qt4中,槽函数必须放在由slots修饰的代码块中 ,并且要使用访问控制符进行访问控制,原则和其他函数一样。
- 信号只需要声明,不需要实现;槽函数需要声明也需要实现。