前言:
在Qt中,有一种回调技术的替代方法:那就是信号和槽机制。当特定事件发生时,会发出一个信号。Qt的小部件中有许多预定义的信号,但我们可以将小部件子类化,向它们添加自定义的信号。槽是响应特定信号的函数。
目录
按钮控件头文件:#include
- #include "mywidget.h"
- #include
-
-
-
- myWidget::myWidget(QWidget *parent)
- : QWidget(parent)
- {
- //创建一个按钮
- QPushButton * btn = new QPushButton;
- //btn->show();//show以顶层方式弹出窗口控件
- //让btn对象 依赖在myWidget窗口中
- btn->setParent(this);
-
- //显示文本
- btn->setText("第一个按钮");
-
- }
-
- myWidget::~myWidget()
- {
- }
-

- #include "mywidget.h"
- #include
-
-
-
- myWidget::myWidget(QWidget *parent)
- : QWidget(parent)
- {
-
- //创建第二个按钮,按照控件大小创建窗口
- QPushButton * btn2 = new QPushButton("第二个按钮",this);
-
- //移动btn2按钮
- btn2->move(100,100);
-
- //重置窗口大小
- resize(600,400);
-
- //设置固定窗口大小
- setFixedSize(600,400);
-
- //设置窗口标题
- setWindowTitle("窗口");
- }
-
- myWidget::~myWidget()
- {
- }
-

当创建的对象在堆区时候,如果指定的父亲是object派生下来的类或者.QObject子类派生下来的类,可以不用管理释放的操作,将对象会放入到对象树中。一定程度上简化了内存回收机制



- #ifndef MYPUSHBUTTON_H
- #define MYPUSHBUTTON_H
-
- #include
-
- class MyPushButton : public QPushButton
- {
- Q_OBJECT
- public:
- explicit MyPushButton(QWidget *parent = nullptr);
-
- ~MyPushButton();
- signals:
-
- };
-
- #endif // MYPUSHBUTTON_H
- #include "mypushbutton.h"
- #include
-
- MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
- {
- qDebug() << "我的按钮类构造调用";
- }
-
- MyPushButton ::~MyPushButton()
- {
- qDebug() << "我的按钮类析构";
- }
- #include "mywidget.h"
- #include
- #include
- #include
-
- myWidget::myWidget(QWidget *parent)
- : QWidget(parent)
- {
-
- //创建一个自己按钮的对象
- MyPushButton * myBtn = new MyPushButton;
- myBtn->setText("我自己的按钮");
-
- myBtn->move(200,0);
- myBtn->setParent(this); //设置到对象树中
- }
-
- myWidget::~myWidget()
- {
- qDebug() << "myWidget的析构调用";
- }
-

坐标系:
以左上角为原点(0,0)X向右增加 Y向下增加

其坐标相对于父窗口而言
connect(信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽))
信号槽的优点:
松散耦合﹐信号发送端和接受端本身是没有关联的,通过connect连接将两端耦合在一起

参数1 信号的发送者
参数2 发送的信号(函数的地址)
参数3 信号的接受者
参数4 处理的槽函数(函数的地址)
- #include "mywidget.h"
- #include
- #include
- #include
-
- myWidget::myWidget(QWidget *parent)
- : QWidget(parent)
- {
-
- //创建一个自己按钮的对象
- MyPushButton * myBtn = new MyPushButton;
- myBtn->setText("我自己的按钮");
-
- myBtn->move(200,0);
- myBtn->setParent(this); //设置到对象树中
-
- //需求 点击我的按钮关闭窗口
- //参数1 信号的发送者 参数2 发送的信号(函数的地址) 参数3 信号的接受者 参数4 处理的槽函数
- //connect(myBtn,&MyPushButton::clicked,this,&myWidget::close);
- connect(myBtn,&QPushButton::clicked,this,&QWidget::close);
- }
-
- myWidget::~myWidget()
- {
- qDebug() << "myWidget的析构调用";
- }
-
写到signals下
返回void
需要声明,不需要实现
可以有参数,可以重载
返回void
需要声明,也需要实现
可以有参数,可以重载
写到public slot下或者public或者全局函数。
需要利用函数指针明确指向函数地址
void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry; void(Student:: *studentSlot)(QString) = &Student::treat; connect(zt,teacherSignal,st,studentSlot);
QsString ----》char *先转成OByteArray(.toUtf8())再转char *()
无参信号和槽的连接 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);
- #ifndef STUDENT_H
- #define STUDENT_H
-
- #include
-
- class Student : public QWidget
- {
- Q_OBJECT
- public:
- explicit Student(QWidget *parent = nullptr);
-
- signals:
-
- public slots:
- //早期qt版本 必须写到public slots,高版本可以写到public或者全局下
- //返回值 void,需要声明也需要实现
- //可以有参数,可以发生重载
- void treat();
- };
-
- #endif // STUDENT_H
- #ifndef TEACHER_H
- #define TEACHER_H
-
- #include
-
- class Teacher : public QObject
- {
- Q_OBJECT
- public:
- explicit Teacher(QObject *parent = nullptr);
-
- signals:
- //自定义信号 写到signals下
- //返回值是void,只需要声明,不需要实现
- //可以有参数,可以重载
- void hungry();
-
-
- };
-
- #endif // TEACHER_H
- #ifndef WIDGET_H
- #define WIDGET_H
-
- #include
- #include
- #include
-
- 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
- #include "student.h"
- #include
- Student::Student(QWidget *parent) : QWidget(parent)
- {
-
- }
-
- void Student::treat()
- {
- qDebug()<<"请老师吃饭";
-
- }
- void Student::treat(QString foodName)
- {
-
- //QsString ----》char *先转成OByteArray(.toUtf8())再转char *()
-
- qDebug()<<"请老师吃饭,老师要吃"<
toUtf8().data(); - }
- #include "teacher.h"
-
- Teacher::Teacher(QObject *parent) : QObject(parent)
- {
-
- }
- #include "widget.h"
- #include "ui_widget.h"
- #include
-
- //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);
-
-
-
- }
-
- void Widget::classIsOver()
- {
- //下课函数调用后触发老师饿了的信号
- //emit zt->hungry();
- emit zt->hungry("鱼香肉丝");
-
- }
- Widget::~Widget()
- {
- delete ui;
- }
-

C++11中的Lambda 表达式用于定义并创建匿名的函效对象,以简化编程工作。
[] 标识符 匿名函数
= 值传递
& 引用传递
() 参数 {} 实现体
mutable 修饰 值传递变量,可以修改拷贝出的数据,改变不了本体
返回值 []() -> int {}
最常用 [=](){}
- //利用Lambda表达式,实现点击按钮关闭窗口
- QPushButton *btn2 = new QPushButton;
- btn2->setText("关闭");
- btn2->move(100,0);
- btn2->setParent(this);
- connect(btn2,&QPushButton::clicked,this,[=](){
- // this->close();
- // emit zt->hungry("鱼香肉丝");
- btn2->setText("AAAAA");
- });
