1. 说明
实际是观察者模式的一种简易方式,使用connect函数可以为信号以及槽建立好连接,当信号广播(触发)时槽做出相应的处理。其中,信号来源于被观察者,槽来源于观察者。
**信号:**函数声明,无需实现
**槽:**本质是函数,一般是类的成员函数,有声明且有实现
2. 信号连接方式
第一种:
使用SIGNAL和SLOT关键字,这样可以在信号和槽中进行参数传递
//创建按钮
QPushButton* btn = new QPushButton();
//设置位置
btn->move(150,200);
//设置大小
btn->resize(100,30);
btn->setText("窗口最大");
//设置字体
QFont font("楷体",15,1);
btn->setFont(font);
btn->setParent(this);
//设置样式
btn->setStyleSheet("QPushButton{background-color:lightblue;}\
QPushButton:hover{background-color:lightgreen;}\
QPushButton:pressed{background-color:rgba(170,155,221,1);}");
btn->show();
//创建信号连接(第一中方式:使用SIGNAL和SLOT关键字,可传递参数)
connect(btn,SIGNAL(clicked(bool)),this,SLOT(showMaximized()));
第二种:
使用地址作用域的方式,此种方式针对有多个信号和槽函数的时候不太友好
auto btnMin = new QPushButton("窗口正常",this);
btnMin->move(100,100);
//设置大小
btnMin->resize(100,30);
//设置字体
QFont font2("楷体",15,1);
btnMin->setFont(font2);
btnMin->setParent(this);
//设置样式
btnMin->setStyleSheet("QPushButton{background-color:lightblue;}\
QPushButton:hover{background-color:lightgreen;}\
QPushButton:pressed{background-color:rgba(170,155,221,1);}");
//创建信号连接(第二种连接方式,不可传递参数)
connect(btnMin,&QPushButton::clicked,this,&QWidget::showNormal);
第三种:
使用C++11中的Lambda新特性
语法:
[可访问外部变量](参数表)->返回值{
函数体 } **返回值为空时可省略**
1:[变量1,变量2,...](){
} 指定部分变量可访问
2:[=](){
} 值传递方式捕获所有外部变量(内部无法改变实际变量)
3:[&](){
} 引用方式捕获所有外部变量(内部可以改变实际变量)
示例:
auto btnTest = new QPushButton("测试按钮",this);
btnTest->move(100,100);
//设置大小
btnTest->resize(100,30);
//设置字体
QFont font3("楷体",15,1);
btnTest->setFont(font3);
btnTest->setParent(this);
//设置样式
btnTest->setStyleSheet("QPushButton{background-color:lightblue;}\
QPushButton:hover{background-color:lightgreen;}\
QPushButton:pressed{background-color:rgba(170,155,221,1);}");
//创建信号连接(第二种连接方式,Lambda表达式)
connect(btnTest,&QPushButton::pressed,[]()->void{
qDebug()<<"按钮被按下....";
});
connect(btnTest,&QPushButton::released,[](){
qDebug()<<"按钮被抬起....";
});
3. 自定义信号和槽
信号自定义时,使用关键字signals,只需要定义,不用实现
槽函数自定义时,使用public slots,需要实现
举例:
首先在头文件中定义信号和槽函数:
signals:
void printInfo();
public slots:
void onPrintInfo();
然后在界面中添加一个按钮,点击按钮后,发射自定义的信号,同时将自定义的信号和自定义的槽函数进行绑定:
auto selfBtn = new QPushButton("测试");
selfBtn->move(100,100);
//设置大小
selfBtn->resize(100,30);
//设置字体
QFont font4("楷体",15,1);
selfBtn->setFont(font4);
selfBtn->setParent(this);
//设置样式
selfBtn->setStyleSheet("QPushButton{background-color:lightblue;}\
QPushButton:hover{background-color:lightgreen;}\
QPushButton:pressed{background-color:rgba(170,155,221,1);}");
//点击按钮后,发射自定义信号
connect(selfBtn,&QPushButton::clicked,this,[=](){
emit printInfo();
});
//将自定义的信号和自定义的槽绑定
connect(this,&Widget::printInfo,this,&Widget::onPrintInfo);
//槽函数的简单实现
void Widget::onPrintInfo()
{
qDebug()<<"输出一些打印信息...";
}
4. 信号槽重载
关于信号和槽若有重载,则在连接信号和槽时,可以借助函数指针进行连接,使用SIGNAL和SLOT关键字的形式进行连接也是可以的。
首先,定义两个重载的信号和槽:
signals:
void printInfo();
void printInfo(QString mStr);
public slots:
void onPrintInfo();
void onPrintInfo(QString str);
然后在源文件中对两个重载的槽函数进行实现:
void Widget::onPrintInfo()
{
qDebug()<<"输出一些打印信息...";
}
void Widget::onPrintInfo(QString str)
{
qDebug()<<str;
}
最后进行连接时需要使用函数指针找到指定的信号和槽:
auto selfBtn = new QPushButton("测试");
selfBtn->move(btnTest->x(),btnTest->y()+50);
//设置大小
selfBtn->resize(100,30);
//设置字体
QFont font4("楷体",15,1);
selfBtn->setFont(font4);
selfBtn->setParent(this);
//设置样式
selfBtn->setStyleSheet("QPushButton{background-color:lightblue;}\
QPushButton:hover{background-color:lightgreen;}\
QPushButton:pressed{background-color:rgba(170,155,221,1);}");
connect(selfBtn,&QPushButton::clicked,this,[=](){
emit printInfo();
emit printInfo("带参数的信号...");
});
//定义函数指针,指向对应的信号和槽函数
void(Widget::*printSignal)() = &Widget::printInfo;
void(Widget::*printSlot)() = &Widget::onPrintInfo;
void(Widget::*printSignalStr)(QString) = &Widget::printInfo;
void(Widget::*printSlotStr)(QString) = &Widget::onPrintInfo;
//信号槽连接
connect(this,printSignal,this,printSlot);
connect(this,printSignalStr,this,printSlotStr);
5. 断连
在一个信号连接了多个槽函数后,如果想让其中一对信号槽不在产生作用,可以将其断开连接,使用函数disconnect,用法和connect一样。
disconnect(this,&Widget::printInfo,this,&Widget::onPrintInfo);