Qt的信号与槽机制

什么是信号与槽机制

在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 
#include 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函数,我们将会在另一篇文章里详细分享。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部