QT-信号和槽
main.cpp
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
wedget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include "teacher.h" #include "student.h" namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private: Ui::Widget *ui; Teacher * zt; Student * st; void classIsOver(); }; #endif // WIDGET_H
wedget.cpp
#include "widget.h" #include "ui_widget.h" #include <QPushButton> #include <QDebug> //Teacher 类 老师类 //Student 类 学生类 //下课后 ,老师会触发一个信号,饿了 ,学生响应信号,请客吃饭 void func() { qDebug() <<"aaa"; } 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、信号和槽的参数个数 是不是要一致?信号的参数个数 可以多余槽函数的参数个数 //Qt4版本以前的信号和槽连接方式 //利用Qt4信号槽 连接无参版本 //Qt4版本 底层SIGNAL("hungry") SLOT( "treat") connect(zt,SIGNAL(hungry()) , st , SLOT(treat())); //Qt4版本优点:参数直观,缺点 :类型不做检测 //Qt5以上 支持 Qt4的版本写法,反之不支持 // QPushButton * btn2 = new QPushButton; // [btn](){ // btn->setText("aaaa"); // btn2->setText("bbb"); //btn2看不到 // }(); // mutable关键字 用于修饰值传递的变量,修改的是拷贝,而不是本体 // QPushButton * myBtn = new QPushButton (this); // QPushButton * myBtn2 = new QPushButton (this); // myBtn2->move(100,100); // int m = 10; // 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->close(); // emit zt->hungry("宫保鸡丁"); btn2->setText("aaaa"); }); //lambda表达式 最常用 [=](){} =值传递 &引用传递 } void Widget::classIsOver() { //下课函数,调用后 触发老师饿了的信号 //emit zt->hungry(); emit zt->hungry("宫保鸡丁"); } Widget::~Widget() { delete ui; }
teacher.h
#ifndef TEACHER_H #define TEACHER_H #include <QObject> class Teacher : public QObject { Q_OBJECT public: explicit Teacher(QObject *parent = 0); signals: //自定义信号 写到signals下 //返回值是void ,只需要声明,不需要实现 //可以有参数,可以重载 void hungry(); void hungry(QString foodName); public slots: }; #endif // TEACHER_H
teacher.cpp
#include "teacher.h" Teacher::Teacher(QObject *parent) : QObject(parent) { }
student.h
#ifndef STUDENT_H #define STUDENT_H #include <QObject> class Student : public QObject { Q_OBJECT public: explicit Student(QObject *parent = 0); signals: public slots: //早期Qt版本 必须要写到public slots,高级版本可以写到 public或者全局下 //返回值 void ,需要声明,也需要实现 //可以有参数,可以发生重载 void treat(); void treat(QString foodName); }; #endif // STUDENT_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() ; }
天道酬勤 循序渐进 技压群雄