需求:定义teacher和student类,实现下课后,老师发出饿信号,学生请客吃饭
- 新建项目,项目名称为SignalsAndSlots,基类选择QWidget
建立完成后,项目界面如下所示:
右键点击项目名称SignalsAndSlots,选择添加新文件,选择C++ class
建立Teacher类,基类选择QObject,界面如下所示:
同理添加Student类,选择基类QObject,添加完成后,界面如下所示:
红色所示为新添加的student和teacher类。
建立好项目后,对需求进行实现,首先对teacher.h自定义饿信号,代码如下:
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号需要写到signlas下
//信号返回类型必须为void
//信号只需要声明,不需要实现
//信号可以有参数,可以重载
void hungry();
public slots:
};
#endif // TEACHER_H
关于自定义信号,注意事项如下:
- 自定义信号需要写到signals
- 信号返回类型必须为void
- 信号只需要声明,不需要实现
- 信号可以有参数,可以重载
student.h定义槽函数,做修改如下:
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
//自定义槽函数最好写在slots下
//返回类型void
//需要声明,也需要实现
//槽函数可以有参数,也可以重载
void treat();
};
#endif // STUDENT_H
自定义槽函数注意事项如下:
- 自定义槽函数最好写在slots下
- 返回类型void
- 需要声明,也需要实现
- 槽函数可以有参数,也可以重载
studen.cpp实现槽函数如下:
#include "student.h"
#include<QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat()
{
qDebug()<<"请客吃饭";
}
widget.h中包含teacher.h和studen.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 = 0);
Teacher* zt;
Student* st;
void classOver();
~Widget();
};
#endif // WIDGET_H
widget.cpp中进行具体实现
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//将zt,st对象与widget绑定,不用考虑内存释放问题
zt = new Teacher(this);
st = new Student(this);
//老师发出饿信号,学生请客吃饭
connect(zt,&Teacher::hungry,st,&Student::treat);
//下课信号发出,触发老师饿信号
classOver();
}
void Widget::classOver()
{
//触发信号
//老师饿属于自定义信号,触发自定义信号需要emit关键字
emit zt->hungry();
}
Widget::~Widget()
{
}
输出结果如下:
接下来增加信号和槽函数的有参函数,并进行信号传递
teacher.h信号中增加有参信号
void hungry(QString foodname);
student.h槽函数增加有参槽函数
void treat(QString foodname);
student.cpp对有参槽函数进行实现
void Student::treat(QString foodname)
{
//qDebug()<<"请客吃饭,吃"<<foodname<<endl;
//将QString转换为char*类型
qDebug()<<"请客吃饭,吃"<<foodname.toUtf8().data();
}
widget.cpp中classover增加对有参函数的触发,并传入参数
void Widget::classOver()
{
//触发信号
//老师饿属于自定义信号,触发自定义信号需要emit关键字
//emit zt->hungry();
//触发有参信号
emit zt->hungry("宫保鸡丁");
}
widget.cpp中Widget构造函数中增加对有参信号和槽函数的处理,为了调用有参函数,定义有参函数指针,指向函数
//函数指针,指向有参函数
void(Teacher:: * teacherSignal)(QString) = &Teacher::hungry;
void(Student:: * studentSlot)(QString) = &Student::treat;
connect(zt,teacherSignal,st,studentSlot);
结果如下:带“ ”为QString类型,不带“ ”为char*类型
- 利用按钮控制下课信号
对widget.cpp进行修改如下:
#include "widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//将zt,st对象与widget绑定,不用考虑内存释放问题
zt = new Teacher(this);
st = new Student(this);
QPushButton* btn = new QPushButton("click",this);
resize(600,400);
//老师发出饿信号,学生请客吃饭
//connect(zt,&Teacher::hungry,st,&Student::treat);
//下课信号发出,触发老师饿信号
//函数指针,指向有参函数
void(Teacher:: * teacherSignal)(QString) = &Teacher::hungry;
void(Student:: * studentSlot)(QString) = &Student::treat;
connect(zt,teacherSignal,st,studentSlot);
//利用按钮触发信号
connect(btn,&QPushButton::clicked,this,&Widget::classOver);
//classOver();
}
void Widget::classOver()
{
//触发信号
//老师饿属于自定义信号,触发自定义信号需要emit关键字
//emit zt->hungry();
//触发有参信号
emit zt->hungry("宫保鸡丁");
}
Widget::~Widget()
{
}
每次点击按钮,输出“请客吃饭,吃 宫保鸡丁”,结果如下:
信号和槽知识补充:
- 信号可以连接信号
- 一个信号可以连接多个槽函数
- 多个信号可以连接一个槽函数
- 信号参数个数可以多余槽参数个数,但是类型必须一一对应