Qt中的信号和槽
点击按钮,实现关闭窗口功能
connect(信号的发送者(指针),发送的信号(地址),信号的接收者(指针),处理信号(槽函数 地址))
connect(myBtn,&MyPushButton::clicked,this,&Widget::close);
自定义信号和槽
需求:下课后,老师会发出饿了的信号,学生进行响应,请老师吃饭
Teacher类和Student类

自定义信号
自定义信号 写到signals下
1、返回值是void
2、只需要声明,不需要实现
3、可以有参数,可以发生重载

自定义槽
槽函数 写到public slots下,或者public、全局函数、lambda
1、返回值 void
2、需要声明 需要实现
3、可以有参数 可以重载

cpp中需要实现的 student.h

测试
widget.h 有老师和学生的指针还有下课函数

widget.cpp 初始化两个指针,连接信号与槽,调用下课函数接可以响应老师的请求

案列改为有参构造,即加上老师要吃的东西
student.h中进行修改

teacher.h中进行修改

widget.cpp中进行修改
ps:qt版本为6.x的可以不加&,但是加了之后可以兼容低版本也可以有智能提示

想要输出结果不带“”
在student.cpp中进行修改

输出结果

信号和槽的扩展
1、信号连接信号
2、一个信号可以连接多个槽函数
3、多个信号可以绑定同一个槽函数
4、信号和槽的参数类型 必须一一对应
5、信号的参数个数可以多于槽函数,反之不可以,相同个数的参数类型也要一一对应(前几个参数)
6、可以利用 disconnect 断开信号槽的连接
将上个例子改成按下课按钮才能触发
#include "widget.h"
#include<QPushButton>
//Teacher 类 Student 类
//下课后,老师会发出饿了的信号,学生进行响应,请老师吃饭
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
this->zt = new Teacher(this);
this->st = new Student(this); //加了(this)会自动调用析构函数
//连接信号和槽
//connect(this->zt,&Teacher::hungry,this->st,&Student::treat);
//连接有参信号和槽
//函数指针指向函数地址 QString代表参数
// void(Teacher:: * teacherSignal)(QString) = &Teacher::hungry;
// void(Student:: * studentSlot)(QString) = &Student::treat;
// connect(this->zt, teacherSignal ,this->st, studentSlot );
//点击按钮才触发请吃饭
QPushButton * btn = new QPushButton;
btn->setParent(this);
btn->setText("下课");
//老师和学生之间的连接
void(Teacher:: * teacherSignal)() = &Teacher::hungry;
void(Student:: * studentSlot)() = &Student::treat;
connect(this->zt, teacherSignal ,this->st, studentSlot );
connect(btn,&QPushButton::clicked,this->zt,teacherSignal);
//想要调用有参的可以使用lambda表达式,这里无法调用的原因是clicked的参数是bool类型的,后边的参数只能是bool或者无参
//disconnect(btn,&QPushButton::clicked,this->zt,teacherSignal);
//下课函数调用
//classISOver();
}
void Widget::classISOver()
{
//触发自定义信号
emit this->zt->hungry();
//触发有参信号
emit this->zt->hungry("汉堡");
}
Widget::~Widget()
{
}
lambda表达式
如果是低版本的qt,需要在pro文件中添加 CONFIG += c++11
QPushButton * btn2 = new QPushButton;
btn2->move(100,0);
btn2->setParent(this);
btn2->setText("Lambda");
//= 函数体内可以使用Lambda所在作用范围内所有可见的局部变量(值传递)
[=](){
btn2->setText("hi");
}();
QPushButton * mybtn1 = new QPushButton;
QPushButton * mybtn2 = new QPushButton;
mybtn1->move(0,100);
mybtn2->move(100,100);
mybtn1->setParent(this);
mybtn2->setParent(this);
int m=10;
//修改m(值传递),看看是只改了这里的m还是原来定义的m(只改了这个地方的)
connect(mybtn1,&QPushButton::clicked,this,[m]()mutable {m=20;qDebug()<<m;});
connect(mybtn2,&QPushButton::clicked,this,[=](){qDebug()<<m;});
qDebug()<<m;
//->返回值类型
int num=[]()->int{return 100;}();
qDebug()<<"num="<<num;
//[=](){}推荐使用
QPushButton * btn3=new QPushButton;
btn3->setParent(this);
btn3->move(200,200);
btn3->setText("aaa");
//再点击按钮后改变按钮的名字
//lambda表达式可以把第三个参数省略(重载)
connect(btn3,&QPushButton::clicked,this,[=](){
btn3->setText("ccc");
this->st->treat("鱼香肉丝"); //不能直接用上边的connect连接有参构造函数,因为clicked函数的参数是bool类型,这里可以用函数来调用
this->close(); //关闭窗口
});
这里放一张图
