头文件
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include "teacher.h"//导入老师头文件
#include "student.h"//导入学生头文件
#include <QWidget> //父类
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }//命名空间
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
Teacher * zt;//指针
Student * st;
public:
void classOver();//方法函数
};
#endif // WIDGET_H
teacher.h
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
槽函数定义
signals:
void hungry();//老师饿了
//可以有参数,可以发生重载
void hungry(QString foodName);
自定义信号 写到signals下 返回值是void ,只需要声明,不需要实现 可以有参数,可以重载
};
#endif // TEACHER_H
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:
void treat();//学生请客
void treat(QString foodName);
};
#endif // STUDENT_H
源文件
main.cpp(略)
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
创建一个老师对象,一个学生对象
this->zt = new Teacher(this);
this->st = new Student(this);
老师饿了,学生请客
connect(zt,&Teacher::hungry,this->st,&Student::treat);
调用下课函数
classOver();
//连接带参数的 信号和槽
// 指针->地址
void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
void(Student:: *studentSlot)(QString) = &Student::treat;
connect(zt,teacherSignal,st,studentSlot);
classOver();
//点击一个下课按钮,再触发下课
QPushButton * btn = new QPushButton("下课",this);
//重置窗口大小
this->resize(600,400);
//点击按钮,触发下课
connect(btn,&QPushButton::clicked,this,&Widget::classOver);
无参信号和槽连接
void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry;
void(Student:: *studentSlot2)(void) = &Student::treat;
connect(zt,teacherSignal2,st,studentSlot2);
//信号连接信号
connect(btn,&QPushButton::clicked,zt,teacherSignal2);
//断开信号
disconnect(zt,teacherSignal2,st,studentSlot2);
信号可以连接信号
一个信号可以连接多个槽函数
多个信号 可以 连接 同一个槽函数
信号和槽函数的参数 必须类型一一对应
信号和槽的参数 个数 可以不一致,信号的参数个数可以多于槽函数参数个数
Qt4版本以前的信号和槽连接方式:利用Qt4信号槽 连接无参版本
connect(zt,SIGNAL(hungry()),st,SLOT(treat()));
Qt4版本的优点:参数直观 缺点:类型不做检测
Lambda表达式
C++11版本特性 [CONFIG += c++11] 匿名函数对象
Lambda表达式函数声明 {}
[=] 允许使用局部变量
[&] 允许使用引用传递变量
[变量] 允许变量使用值传递
mutable 可修改值传递进来的参数[虽然还是局部变量]
mmutable{m+=100;打印}; 不加mutable会报错
->类型 带返回值
int ret = ->int{return 1000}();
Lambda表达式函数调用 {}()
最常见的={}
QPushButton * btn2 = new QPushButton(this);
[=](){
btn->setText("aaa");
btn2->setText("bbb");
}();
QPushButton * myBtn = new QPushButton("myBtn",this);
QPushButton * myBtn2 = new QPushButton("myBtn2",this);
myBtn->move(50,50);
myBtn2->move(100,100);
int m = 10;
//mutable 关键字 用于修饰值传递的变量,修改的是拷贝,而不是本体
connect(myBtn,&QPushButton::clicked,this,[m] () mutable{m=100+10;qDebug()<<m;});
connect(myBtn2,&QPushButton::clicked,this,[=] (){qDebug()<<m;});
qDebug()<<m;
int ret = []()->int{return 1000;}();
qDebug()<<"ret"<<ret;
利用lambda表达式,实现点击按钮,关闭窗口
QPushButton * btn2 = new QPushButton;
btn2->setText("关闭");
btn2->move(100,0);
btn2->setParent(this);
connect(btn2,&QPushButton::clicked,this,[=](){
//this->close();
emit zt->hungry("宫保鸡丁");
});
//lambda表达式 最常用[=](){}
}
void Widget::classOver(){
//下课函数,调用后,触发老师饿了的信号
emit zt->hungry("宫保鸡丁");
}
Widget::~Widget()
{
delete ui;
}
teacher.cpp
#include "teacher.h"
Teacher::Teacher(QObject *parent)
: QObject{parent}
{
}
student.cpp
#include "student.h"
#include <QDebug>
Student::Student(QObject *parent)
: QObject{parent}
{
}
void Student::treat(){
qDebug() << "请老师吃饭";
}
void Student::treat(QString foodName){
//QString -> char * 先转成 QByteArray ( .toUtf8() ) 再转char *( .data() )
qDebug() <<"请老师吃饭,老师要吃"<<foodName.toUtf8().data();
}