- 信号和槽
- (1)连接函数:connect
- (2)参数:参数1 信号的发送者 参数2 发送的信号 参数3 信号的接受者 参数4 处理的槽函数(函数的地址)
- (3)松散耦合
- (4)实现 点击按钮 关闭窗口
- (5)connect(wBtn,&WpushButton::clicked,this,&wwidget::close);
- 2.自定义信号和槽
- (1)定义信号
- (1.1)写到signals下
- (1.2)返回void
- (1.3)需要声明,不需要实现
- (1.4)可以有参数,可以重载
- (2)自定义槽函数
- (2.1)返回void
- (2.2)需要声明,也需要实现
- (2.3)可以有参数,可以重载
- (2.4)写到public slot下 或者 public 或者全局函数
- (3)触发自定义信号
- (3.1)emit自定义信号
- (4)案例:下课后,老师触发饿了信号,学生响应信号,请客吃饭
-
student.h #ifndef STUDENT_H #define STUDENT_H #include <QObject> class Student : public QObject { Q_OBJECT public: explicit Student(QObject *parent = nullptr); //返回值 void 需要声明 需要实现 //可以有参数 可以发生重载 void treat(); void treat(QString foodName); signals: }; #endif // STUDENT_H
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
widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include "teacher.h" #include "student.h" 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; void classIsOver(); }; #endif // WIDGET_H
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(); }
widget.cpp #include "widget.h" #include "ui_widget.h" #include "QPushButton" //teacher类 老师类 //student类 学生类 //下课后,老师触发一个信号,饿了,学生相应信号,请客吃饭 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,st,&Student::treat); // //调用下课函数 // classIsOver(); //连接带参数的 信号和槽 //指针->地址 //函数指针->函数地址 void (Teacher::*teacherSignal)(QString) = &Teacher::hungry; void (Student::*studentSlot)(QString) = &Student::treat; connect(zt,teacherSignal,st,studentSlot); //classIsOver(); //点击一个 下课按钮 再触发下课 QPushButton * btn = new QPushButton("下课",this); //重置窗口大小 this->resize(600,400); //点击按钮 触发下课 //connect(btn,&QPushButton::clicked,this,&Widget::classIsOver); //无参信号和槽连接 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); //拓展 //1.信号是可以连接信号 //2.一个信号可以连接多个槽函数 //3.多个信号 可以连接 同一个槽函数 //4.信号和槽函数的参数类型必须一一对应 //5.信号的参数个数 可以多于槽函数的参数个数 //Qt版本以前的信号和槽链接方式 //利用Qt4信号槽 连接无参版本 //Qt4版本 底层SIGNAL("hungry") SLOT("treat") connect(zt,SIGNAL(hungry()), st ,SLOT(treat())); //Qt4版本优点:参数直观,缺点:类型不做检测 //Qt5以上 支持Qt4的版本写法,反之不支持 } void Widget::classIsOver() { //下课函数,调用后 触发老师饿了的信号 emit zt->hungry("宫保鸡丁"); } Widget::~Widget() { delete ui; }
3.当自定义信号和槽出现重载
- (1)需要利用函数指针,明确指向函数的地址
- (2)void (Teacher::*teacherSignal)(QString) = &Teacher::hungry;
- (3)QString 转成 char *
- (3.1).toUtf8()转为QByteArray
- (3.2).data()转为*char
- (5)断开信号 dicconnect
- 4. 拓展
- (1)信号可以连接信号
- (2)一个信号可以连接多个槽函数
- (3)多个信号可以连接同一个槽函数
- (4)信号和槽函数的参数 必须类型一一对应
- (5)信号的参数个数 可以多于槽函数的参数个数
- (6)信号槽可以断开连接 disconnect
- 5.Q4版本写法
- (1)connect(信号的发送者,发送的信号 SIGNAL(信号),信号接受者,槽函数 SLOT(槽函数))
- (2)优点 参数直观
- (3)缺点 编译器不会检测参数类型