信号与槽用于两个对象之间,当一个部件发生改变时,希望其他部件也能了解到该变化,也希望任何对象与其他对象进行通信。
Qt封装了具体操作系统的消息机制,遵循经典的GUI消息驱动事件模型。 消息驱动机制
QT定义了与操作系统消息相关的自己的概念,即信号与槽。
信号signal是由操作系统产生的消息。
槽slot是程序中的消息处理函数。
connect将系统消息绑定到消息处理函数。
信号到槽的连接必须发生在两个QT对象间。
bool QObject::connect (
const QObject * sender, //发生对象
const char * signal, //消息名
const QObject * receiver, //接收对象
const char *method, //接收对象的成员函数
Qt::ConnectionType type = Qt::AutoConnection )
eg:
connect(ui->btn, &QPushButton::clicked, this, &MainWindow::change_state);
connect(ui->btn, SIGNAL(clicked()), this, SLOT(change_state()));//qt4
信号和槽机制的特色和优越性:
信号和槽机制是类型安全的,相关联的信号和槽的参数必须匹配;
信号和槽是松耦合的,信号发送者不知道也不需要知道接受者的信息;
信号和槽可以使用任意类型的任意数量的参数。
虽然信号和槽机制提供了高度的灵活性,但就其性能而言,还是慢于回调机制的。回调函数 性能差异在应用程序中还是很难体现出来的
需要继承自QObject或其子类;在类声明的最开始处添加Q_OBJECT宏;槽中的参数的类型要和信号的参数的类型相对应,且不能比信号的参数多;信号只用声明,没有定义,且返回值为void类型。声明一个信号要使用signals关键字,在signals前面不能使用public、private和protected等限定符因为只有定义该信号的类及其子类才可以发射该信号。 槽是普通的成员函数,也有访问权限。
槽函数就是一个普通函数,在没有与信号一起使用的时候,可以以普通成员函数的方式来使用 鼠标右键点击发送信号的控件,选择转到槽,选择对应的信号,会在.cpp中生成槽函数,在槽函数内部编写要执行的代码(行为)。
在接收信号的类里面声明槽函数,槽函数的定义跟类的普通成员函数定义方式一样。
在发送信号和接收信号的对象建立之后代码中使用connet函数进行信号与槽函数的连接
在发送信号的类中自定义一个信号,在声明信号的类或派生类发送.
在接收信号的类里面声明槽函数,槽函数的定义跟类的普通成员函数定义方式一样。
在发送信号和接收信号的对象建立之后代码中使用connet函数进行信号与槽函数的连接
自动生成的槽函数命名规范:on_对象名称_对象信号(),在后两种方式中如果槽函数按照这样的命名方式,就可以不写连接。
信号声明在发送信号的类中声明(.h)中
①自定义一个信号
signals:://信号不能像普通函数一样使用,也不需要权限声明
void mysignal();//信号不需要定义
②发送信号
emit mysignal();
接收信号的类中声明槽函数(.h)
private slots://槽函数在类中的声明
void myslot();//槽函数的定义跟类的普通成员函数定义方式一样
//槽函数定义
void MainWindow::myslot()
{
ui->label_2->setText("完成设置");
}
匿名函数方式
qt5支持 c++11中的lambda表达式:
connect(btn,&QpushBtton::clicked,[=](/*参数*/){
//函数体
});
在同时能够看到信号发送者和信号接收者的地方
//绑定信号和槽函数
// connect(this, SIGNAL(mysignal()), this, SLOT(myslot()));
connect(this, &MainWindow::mysignal, this, &MainWindow::myslot);
通过参数来传递
void send_data(QString msg); void recv_data(QString msg);
(1)信号不带参数,槽函数一定不能带参数
(2)信号带参数,槽函数可以不带参数,如果槽函数带参数,得保证类型和信号的参数类型一致
(3)信号参数个数可以是多个,槽函数可以没有,也可以有多个(顺序要与信号的参数一致),也可以有其中的某个
当信号与槽没必要进行保持关联时,可以使用disconnect函数来断开连接
bool QObject::disconnect (
const QObject * sender,
const char * signal,
const QObject * receiver,
const char *method )
disconnect函数断开发送者中的信号与接收者中的槽函数之间的关联。
在disconnect函数中0可以用作一个通配符,分别表示任何信号、任何接收对象、接收对象中的任何槽函数。但是发射者sender不能为0,其它三个参数的值可以等于0。
disconnect(sender,0,0,0);
//sender->disconnect();
disconnect(sender,SIGNAL(mySignal()),0,0);
//sender->disconnect(SIGNAL(mySignal()));
dixsconnect(sender,0,recevier,0);
//sender->disconnect(recevier);