QPushButton *quitBtn = new QPushButton("按钮1",this);
connect(quitBtn,&QPushButton::clicked,this,&MyWidget::close);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-d8e2wisB-1678792590074)(https://typoracole.oss-cn-guangzhou.aliyuncs.com/img/信号和槽链接.gif)]
connect函数是建立信号发送者、信号、信号接收者、槽四者关系的函数:connect(sender, signal, receiver, slot);
注意:connect的四个参数都是指针,信号和槽是函数指针
这里的clicked就是我们要找到,槽函数的寻找方式和信号一样,只不过他的关键字是slot
Qt框架默认提供的标准信号和槽不足以完成我们日常应用开发的需求,但是Qt信号和槽机制提供了允许我们自己设计自己的信号和槽
定义场景:下课了,老师跟同学说肚子饿了(信号),学生请老师吃饭(槽)
signals:
void hungry();
public slots:
void treat();
void Student::treat()
{qDebug() << "Student treat teacher";
}
teacher = new Teacher(this);
student = new Student(this); connect(teacher,&Teacher::hungury,student,&Student::treat);
void MyWidget::ClassIsOver()
{//发送信号emit teacher->hungry();
}
void hungry(QString name); //自定义信号void treat(QString name ); //自定义槽
对于有两个重名的自定义信号和自定义的槽,直接连接会报错,所以需要利用函数指针来指向函数地址, 然后再做连接
//函数重载 函数指定具有二义性需要进行指定
//1.函数指针赋值
void(Teacher::*tqs)(QString)=&Teacher::hungry;//自动赋值对应类型的函数地址
void(Student::*sqs)(QString)=&Student::treat;
connect(pTeacher,tqs,pStudent,sqs);
//2.使用static_cast转换
connect(pTeacher,static_cast(&Teacher::hungry),pStudent,static_cast(&Student::treat));
//3.qt4之前使用宏转换
connect(pTeacher,SIGNAL(hungry()),pStudent,SLOT(treat()));
connect(pTeacher,SIGNAL(hungry(QString)),pStudent,SLOT(treat(QString)));
注:对于使用SIGNAL()和SLOT()宏指定函数,虽然使用简单,但是宏只是做字符串替换,编译时不会检查,所以运行时可能报错
如果是这种情况,这些槽会一个接一个的被调用,但是槽函数调用顺序是不确定的
只要任意一个信号发出,这个槽就会被调用
当第一个信号发出时,第二个信号被发出。除此之外,这种信号-信号的形式和信号-槽的形式没有什么区别。这里还是使用connect函数,只是信号的接收者和槽函数换成另一个信号的发送者和信号函数
使用disconnect函数,当初建立连接时connect参数怎么填的,disconnect里边4个参数也就怎么填。当一个对象delete之后,Qt自动取消所有连接到这个对象上面的槽。
信号函数的参数个数必须大于等于槽函数的参数个数
信号函数的参数类型和槽函数的参数类型必须一一对应
connect(btn,&QPushButton::clicked,[=](){qDebug()<<"Clicked";
});
表达式也会直接运行
3. 当然lambda表达式还可以指定函数参数,这样也就能够接收到信号函数传递过来的参数了
4. 由于lambda表达式比我们自己自定义槽函数要方便而且灵活得多,所以在实现槽函数的时候优先考虑使用Lambda表达式
5. 一般使用习惯也是lambda表达式外部函数的局部变量全部通过值传递捕获进来,也就是:[ = ] ( ) { }的形式