1、信号槽的优点
信号槽的优点,松散耦合,信号发送端和接收端本身没有关联,通过connect连接将两端耦合在一起。
myPushButton *btn3=new myPushButton(this);
btn3->setText("我的按钮");
btn3->move(200,0);
//发送者 信号 ,接收者,处理的槽函数
connect(btn3,&QPushButton::clicked,this,&Widget::close);
2、自定义的信号和槽
自定义信号:
signals:
//自定义信号,写到signals下
//返回值void,需要声明,不用实现
//可以有参数,可以重载
void hungry();
自定义槽函数:
public slots:
//早期Qt版本,必须写到public slots下,高级版本可以写到public或者全局下
//返回值void,需要声明,需要实现
//可以有参数,可以重载
void treat();
案例
下课,老师饿了触发信号,学生响应,请吃饭
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "teacher.h"
#include "student.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Teacher*zt;
Student*st;
void classIsOver();
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
/************信号与槽实验***********/
this->st=new Student(this); //初始化
this->zt=new Teacher(this);
connect(zt,&Teacher::hungry,st,&Student::treat);
classIsOver();
}
Widget::~Widget()
{
}
void Widget::classIsOver()
{
emit zt->hungry();
}
3、信号重载、槽重载
如果信号或者槽函数有重载,那么使用connect
时,传入的地址需要进行处理,connect(zt,&Teacher::hungry,st,&Student::treat);
会报错,产生二义性,无法区分到底是哪个版本的信号/槽函数。此时可以使用函数指针来声明地址。
以下面例子说明:
//Teacher.h
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号,写到signals下
//返回值void,只需要声明,不用实现
//可以有参数,可以重载
void hungry();
void hungry(QString foodname);
};
#endif // TEACHER_H
//student.h
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
#include <QDebug>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
//早期Qt版本,必须写到public slots下,高级版本可以写到public或者全局下
//返回值void,需要声明、实现
//可以有参数,可以重载
void treat();
void treat(QString foodName);
};
#endif // STUDENT_H
//widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
/************信号与槽实验***********/
this->st=new Student(this);
this->zt=new Teacher(this);
// connect(zt,&Teacher::hungry,st,&Student::treat);
// classIsOver();
/************信号与槽重载实验***********/
void(Teacher:: *teacherSiganl)(QString)=&Teacher::hungry;
void(Student:: *studentSlot)(QString)=&Student::treat;
connect(zt,teacherSiganl,st,studentSlot);
classIsOver();
}
Widget::~Widget()
{
}
void Widget::classIsOver()
{
// emit zt->hungry();
emit zt->hungry("宫保鸡丁");
}
QString转为char*
//QString->char* 先转成QByteArray(.toUtf8),再转char*
qDebug()<<"请老师吃饭,吃"<<foodName.toUtf8().data();
4、信号连接信号
信号是可以连接信号的
/************信号连接信号实验***********/
void(Teacher:: *teacherSiganl2)(void)=&Teacher::hungry;
void(Student:: *studentSlot2)(void)=&Student::treat;
//第一种 信号连接槽 ,槽里触发了信号
// connect(btn2,&QPushButton::clicked,this,&Widget::classIsOver);
//第二种 信号连接另一个信号
connect(btn3,&QPushButton::clicked,zt,teacherSiganl2);
//断开信号
disconnect(btn3,&QPushButton::clicked,zt,teacherSiganl2);
//Qt4版本,参数直观,缺点,类型不做检测
connect(zt,SIGNAL(hungry()),st,SLOT(treat()));
- 一个信号是可以连接多个槽函数的
- 多个信号可以连接同一个槽函数
- 注意信号和槽函数的参数类型必须一一对应
- 信号的参数可以多余槽函数的参数个数