什么是信号与槽机制
在C++中,对象与对象之间的通信是要通过调用成员函数的方式来实现的。Qt提供了一种在对象与对象之间的通信方式:信号与槽机制。
在Qt中,如果一个类希望使用信号与槽的功能,那么就必须在其中声明Q_OBJECT,这个宏提供了信号与槽机制、国际化、不基于C++ RTTI的反射能力。
class myconnect: public QWidget{
Q_OBJECT // 声明Q_OBJECT
public:
myconnect(QWidget *parent=nullptr);
~myconnect();
private:
QPushButton button1;
};
信号与槽机制的原理
信号与槽机制的原理:当某个事件发生后,就广播一个信号,如果有对象对这个信号感兴趣,那么就可以使用connect函数,将此信号与自己的一个函数进行绑定。那么当这个信号被发出时,绑定的函数就会被调用。connect函数:
connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot,
Qt::ConnectionType type = Qt::AutoConnection)
- sender: 发出信号的对象
- signal:发出信号的对象发出的信号
- receiver:接收信号的对象
- slot:接收信号的对象在接收信号后执行的函数
myconnect::myconnect(QWidget *parent): QWidget(parent){
button1.setParent(this);
button1.setText("close");
button1.move(100,100);
connect(&button1,&QPushButton::pressed,this,&myconnect::close);
}
信号的绑定
- 一个信号可以绑定多个槽函数:
connect(sender,SIGNAL(signal),receiverA,SLOT(slotA));
connect(sender,SIGNAL(signal),receiverB,SLOT(slotB));
connect(sender,SIGNAL(signal),receiverC,SLOT(slotC));
- 多个信号绑定到同一个槽函数:
connect(senderA,SIGNAL(signalA),receiver,SLOT(slot));
connect(senderB,SIGNAL(signalB),receiver,SLOT(slot));
connect(senderC,SIGNAL(signalC),receiver,SLOT(slot));
-
一个信号绑定到另一个信号:
当sender发送信号给signalA时,receiver在接收到signalA信号时发出信号signalB。
connect(sender,SIGNAL(signalA),receiver,SIGNAL(signalB));
- 将信号与槽函数解绑:
disconnect(sender,SIGNAL(signal),receiver,SLOT(slot));
信号与槽机制与真正的调用函数相比,时间的消耗是很大的,所以在嵌入式的开发中,极不推荐使用信号与槽机制开发。
自定义槽函数
它其实就是一个函数而已,所以只需要把它定义出来,然后把函数指针传给connect函数。
myconnect.h:
#include <QPushButton>
#include <QWidget>
class myconnect: public QWidget{
Q_OBJECT
public:
myconnect(QWidget *parent=nullptr);
void mySlot();
~myconnect();
private:
QPushButton button1;
};
myconnect.cpp:
#include "myconnect.h"
myconnect::myconnect(QWidget *parent): QWidget(parent){
button1.setParent(this);
button1.setText("close");
button1.move(100,100);
connect(&button1,&QPushButton::pressed,this,&myconnect::mySlot);
}
void myconnect::mySlot(){
button1.setText("Open");
}
myconnect::~myconnect(){}
自定义信号
槽函数可以传递参数,我们通过自定义信号的例子一同来说明。
自定义信号是一个函数声明,返回类型是void,不需要任何实现。在声明处用signals标记信号。使用emit在适合地方发送信号。
自定义信号的特点:
- 无须实现
- 返回类型只能是void
- 可以有参数
myconnect.h:
class myconnect: public QWidget{
Q_OBJECT
public:
myconnect(QWidget *parent=nullptr);
void mySlot(QString message); // 自定义带参数的槽函数
~myconnect();
signals:
void mySignal(QString message); // 自定义信号
private:
QPushButton button1;
};
myconnect.cpp:
connect(this,&myconnect::mySignal,this,&myconnect::mySlot);
QString message = "Hello Qt";
emit mySignal(message);
void myconnect::mySlot(QString message){
button1.setText(message);
}
注意:信号函数的参数列表要与槽函数的一致。
槽函数类型
槽函数可以是任何成员函数、静态成员函数、全局函数、Lambda函数。
- 任何成员函数: 如上述的例子
- 全局函数
void hello();
myconnect::myconnect(QWidget *parent): QWidget(parent){
button1.setParent(this);
button1.setText("close");
button1.move(100,100);
connect(&button1,&QPushButton::pressed,this,&hello);
}
void hello(){
qDebug() << "hello 8888";
}
-
静态成员函数
myconnect.h:
class myconnect: public QWidget{
Q_OBJECT
public:
myconnect(QWidget *parent=nullptr);
static void staticHello();
~myconnect();
private:
QPushButton button1;
};
myconnect.cpp
myconnect::myconnect(QWidget *parent): QWidget(parent){
button1.setParent(this);
button1.setText("close");
button1.move(100,100);
connect(&button1,&QPushButton::pressed,this,&myconnect::staticHello);
}
void myconnect::staticHello(){
qDebug() << "hello 8888000";
}
Lambda函数
myconnect::myconnect(QWidget *parent): QWidget(parent){
button1.setParent(this);
button1.setText("close");
button1.move(100,100);
connect(&button1,&QPushButton::pressed,this,[]{
qDebug() << "9999999999";
});
}
关于Lambda函数,我们将会在另一篇文章里详细分享。
版权声明:本文为weixin_40763897原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。