初识qt
- **qt**
- **qt命名规范以及相关快捷键的使用**
- **QPushButton**
- **对象树**
- **点击按钮关闭窗口**
- **信号和槽**
- **标准的信号和槽**
- **自定义信号和槽**
- **带参数的自定义信号和槽传参以及函数的二义性问题**
- **信号和槽的拓展**
- **qt4的信号与槽**
- **QDebug的输出转义问题**
- **lambda表达式**
- **作业:**
qt
qt命名规范以及相关快捷键的使用
优点:Qt相对于C++,有一个很好的机制是,他有自己的一套内存回收机制,在一定程度上简化了内存回收,不需要每每new申请之后总要想着delete了
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>//包含头文件QWidget 窗口类
class Widget : public QWidget
{
Q_OBJECT //Q_OBJECT宏,允许类中使用信号和槽的机制
public:
Widget(QWidget *parent = nullptr);//构造函数
~Widget();//析构函数
};
#endif // WIDGET_H
main.cpp
#include "mywidget.h"
#include <QApplication>//包含一个应用程序类的头文件
//argc命令行变量的数量 argv命令行变量的数组
//应用程序对象,在Qt中,应用程序对象有且仅有一个
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//窗口对象 Widget父类 ->Qwidget
Widget w;
//窗口对象默认不会显示,必须要调用show方法显示窗口
w.show();
//让应用程序对象 进入消息循环机制
//让代码阻塞到这行
return a.exec();
}
项目的代码解释
widget.cpp
#include "widget.h"
//命名规范
//类名 首字母大写,单词和单词之间首字母大写
//函数名 变量名称 首字母小写,单词和单词之间首字母大写
//快捷键
//注释ctrl +l
//运行ctrl + r
//编译ctrl + b
//字体缩放ctrl +鼠标滚轮
//查找 ctrl+f
//整行移动 ctrl+shift+上键或者下键
//帮助文档 F1
//自动对齐 ctrl+i;
//同名直接的.h和.cpp切换 F4
//帮助文档 第一种方式F1
//第二种 左侧按钮
//第三种 路径方式
Widget::Widget(QWidget *parent)
: QWidget(parent)//初始化列表
{
}
Widget::~Widget()
{
}
QPushButton
QPushButton是Qt框架中的一个类,用于创建一个可点击的按钮控件。可以设置按钮的文本、图标、样式等属性,以及连接按钮的点击事件到相应的槽函数。常用于创建用户界面中的交互按钮。
用到类的时候要将模块加入到项目里面
在Qt中,show()是QWidget类的一个成员函数,用于显示窗口小部件。当调用show()函数时,窗口小部件将被显示在屏幕上
在Qt中,QPushButton类确实有一个setParent()函数,可以用于设置按钮的父对象
与上一个一样,前面的头文件和main函数不变
父子关系:
默认情况下.按钮没有认干爹的情况,是顶层窗口
想要按钮显示在窗口上,就要跟窗口构造父子关系
1、setParent
2、构造函数传参
在这个程序中,Widget类的构造函数有一个默认参数parent,因此可以使用无参构造函数来创建Widget对象,也可以使用有参构造函数来创建Widget对象并传递一个parent参数。在main函数中,使用了有参构造函数来创建Widget对象,并将其父对象设置为nullptr,即没有父对象。因此,这个程序可以正常运行。
#include "widget.h"
#include <QPushButton>//按钮控件的头文件
//命名规范
//类名 首字母大写,单词和单词之间首字母大写
//函数名 变量名称 首字母小写,单词和单词之间首字母大写
//快捷键
//注释ctrl +l
//运行ctrl + r
//编译ctrl + b
//字体缩放ctrl +鼠标滚轮
//查找 ctrl+f
//整行移动 ctrl+shift+上键或者下键
//帮助文档 F1
//自动对齐 ctrl+i;
//同名直接的.h和.cpp切换 F4
//帮助文档 第一种方式F1
//第二种 左侧按钮
//第三种 路径方式
Widget::Widget(QWidget *parent)
: QWidget(parent)//初始化列表
{
//创建一个按钮
QPushButton * btn=new QPushButton;
//btn->show();//show的默认是按照顶层方式弹出的控件
//让btn对象 依赖在Widget窗口中
btn->setParent(this);
//显示文本
btn->setText("第一个按钮");
//创建第二个按钮 按照控件的大小来创建窗口
QPushButton * btn2=new QPushButton("第二个按钮",this);
//移动btn2按钮
//第二种方式传入的长和宽
btn2->move(200,200);
按钮可不可以 重新制定大小 可以
//btn->resize(50,50);
//重置窗口的大小
//传入的是长和宽
resize(600,400);
//设置固定的窗口大小
setFixedSize(600,400);
//设置窗口的标题
setWindowTitle("第一个窗口");
}
Widget::~Widget()
{
}
第一个窗口
#include "widget.h"
#include <QPushButton>
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
//添加按钮
// QPushButton btn;
// btn.setText("按钮1");
// //将按钮显示出来
// btn.show();
//默认情况下没有建立父子关系,显示的都是顶层窗口
//要建立父子关系
//1、setParent函数
QPushButton btn;
btn.setText("按钮1");
btn.setParent(&w);//传入的是对象指针
//2、构造函数传参
QPushButton btn2("按钮2",&w);
//移动一下按钮位置
btn2.move(100,100);
btn2.resize(400,400);
//按钮3,和按钮2建立父子关系
QPushButton btn3("按钮3",&btn2);
btn3.move(100,100);
//设置窗口标题
w.setWindowTitle("hello world");
//设置窗口的固定大小
//w.setFixedSize(800,600);
//同时设置窗口的位置和大小
//move和resize的集合体
w.setGeometry(400,400,500,500);
w.show();
//顶层窗口移动到200 100
//是以父窗口的左上角为0,0
//以向左的方向为x的正方向
//以向右的方向为y的正方向
//顶层窗口是以屏幕左上角为0,0
//w.move(200,100);
return a.exec();
}
对象树
对象树之间的父子关系是对象之间的父子关系 不是类直接的父子关系
父对象在释放析构函数的时候还会释放子对象
每个窗口都有child列表
在Qt中,对象树是一种管理对象生命周期的机制。当一个对象被添加到对象树中时,它的父对象会负责管理它的内存分配和释放。这意味着,当父对象被销毁时,它的所有子对象也会被自动销毁,从而避免了内存泄漏和悬挂指针等问题。
在创建一个新的Qt对象时,我们通常需要将它添加到对象树中,以便它能够被正确地管理。这可以通过将它的父对象作为参数传递给它的构造函数来实现。这样,当父对象被销毁时,它的子对象也会被自动销毁,从而保证了对象的正确释放。
总之,传入对象树是Qt中一种重要的管理对象生命周期的机制,可以有效地避免内存泄漏和悬挂指针等问题。
在qt中创建对象的时候会提供一个Parent对象指针,下面来解释这个parent到底是干什么的
QObject是以对象树的形式组织起来的。
当你创建一个QObject对象时,会看到QObject的构造函数接收一个
QObject指针作为参数,这个参数就是 parent,也就是父对象指针。
这相当于,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。
当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类)
这种机制在GUI程序设计中相当有用。例如,一个按钮有一个QShoxtcut(快捷键)对象作为其子子对象。
当我们删除按钮的时候,这个快捷键理应被删除。这是合理的。
构造顺序从上到下,析构顺序从下到上
点击按钮关闭窗口
要四个元素:按钮、被点击、窗口、关闭
建立四者的关系
QPushButton btn = new QPushButton(“按钮1”,this);为啥这段要传入this指针
在Qt中,每个QWidget派生类都有一个父对象,父对象负责管理其子对象的生命周期。在这个例子中,QPushButton的父对象是当前的QWidget,也就是说,当当前的QWidget被销毁时,它的所有子对象也会被自动销毁。因此,将当前QWidget的指针作为QPushButton的父对象传入,可以确保QPushButton的生命周期与当前QWidget的生命周期相同,避免了内存泄漏的问题。
**
Widget::Widget(QWidget parent)
: QWidget(parent)这段代码什么意思
这段代码是一个构造函数,用于创建一个QWidget对象。其中,parent是QWidget对象的父对象,表示该QWidget对象是由哪个QWidget对象创建的。如果没有父对象,可以将parent设置为nullptr或省略。
#include "widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPushButton *btn = new QPushButton("按钮1",this);
//关闭 this->close
//建立四者的关系
connect(btn,&QPushButton::clicked,this,&Widget::close);
}
Widget::~Widget()
{
}
信号和槽
信号和槽机制
信号:各种事件
槽:响应信号的动作
当某个事件发生后,如某个按钮被点击了一下,它就会发出一个被点击的信号(signal)
某个对象接收到这个信号之后,就会做一些相关的处理动作(称为槽slot)。
但是Qt对象不会无故收到某个信号,要想让一个对象收到另一个对象发出的信号,这时候需要建立连接(connect)
*QPushButton btn = new QPushButton(“按钮1”,this);
connect(btn,&QPushButton::clicked,this,&Widget::close);
这两句代码什么意思
这两句代码是在Qt框架下编写的,作用是创建一个名为"按钮1"的QPushButton对象,并将其添加到当前窗口中(this表示当前窗口),然后将该按钮的clicked信号与当前窗口的close槽函数连接起来。也就是说,当用户点击该按钮时,会触发clicked信号,从而执行当前窗口的close槽函数,关闭当前窗口。
具体来说,&QPushButton::clicked是一个信号,表示按钮被点击时会发出该信号;this是当前窗口的指针,表示将该信号连接到当前窗口上;&Widget::close是一个槽函数,表示当按钮被点击时会执行当前窗口的close槽函数,从而关闭当前窗口。
使用了函数指针。这里,我们将btn的clicked信号与Widget对象的close槽函数连接起来,使用了&QPushButton::clicked和&Widget::close来分别表示这两个函数的指针。
#include "widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPushButton *btn = new QPushButton("按钮1",this);
//关闭 this->close
//按钮
//被点击
//窗口
//关闭
//建立四者的关系
connect(btn,&QPushButton::clicked,this,&Widget::close);
//信号发送者
//信号
//信号接收者
//槽:信号的处理动作
//通过connect建立四者的关系
//connect(信号发送者,信号,信号接收者,槽)
}
Widget::~Widget()
{
}
标准的信号和槽
具体有哪些:自己查
标准的槽
标准的信号
继承过来看父类
#include "widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QPushButton *btn = new QPushButton("按钮1",this);
//关闭 this->close
//按钮
//被点击
//窗口
//关闭
//建立四者的关系
//关闭
//connect(btn,&QPushButton::clicked,this,&Widget::close);
//最大化
//connect(btn,&QPushButton::clicked,this,&Widget::showMaximized);
//最小化
connect(btn,&QPushButton::clicked,this,&Widget::showMinimized);
//隐藏 但是在运行 任务管理器可以结束进程
connect(btn,&QPushButton::clicked,this,&Widget::hide);
//信号发送者
//信号
//信号接收者
//槽:信号的处理动作
//通过connect建立四者的关系
//connect(信号发送者,信号,信号接收者,槽)
}
Widget::~Widget()
{
}
指针指向函数时,可以不加&符号,因为函数名本身就代表了函数的地址。
例如:
void func() {
// do something
}
int main() {
void (*p)() = func; // 不加&符号
p(); // 调用函数
return 0;
}
在上面的代码中,p
是一个指向函数的指针,它直接赋值为 func
,不需要加上 &
符号
自定义信号和槽
从上到下依次为
#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();
};
#endif // STUDENT_H
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
void hungry();
public slots:
};
#endif // TEACHER_H
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "student.h"
#include "teacher.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void classIsOver();
private:
Teacher *pTeacher;
Student *pStudent;
};
#endif // WIDGET_H
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
#include "student.h"
#include <QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat()
{
qDebug()<<"Student treat teacher";
}
#include "teacher.h"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
}
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//new的时候要加入对象树
//老师和学生的两个对象创建
pTeacher=new Teacher(this);
pStudent=new Student(this);
//建立连接
connect(pTeacher,&Teacher::hungry,pStudent,&Student::treat);
//下课了
this->classIsOver();
}
void Widget::classIsOver()
{
//触发老师饿了的信号
emit pTeacher->hungry();
}
Widget::~Widget()
{
}
带参数的自定义信号和槽传参以及函数的二义性问题
在上面的场景再引入
void (Teacher::*teacher_qString)(QString)=&Teacher::hungry;啥意思
这行代码定义了一个指向 Teacher
类的成员函数的指针,该成员函数的参数为 QString
类型,函数名为 hungry
。具体来说,Teacher::*teacher_qString
表示指向 Teacher
类的成员函数指针,QString
表示该成员函数的参数类型,&Teacher::hungry
表示该成员函数的地址。这个指针可以用来调用 Teacher
类的成员函数 hungry
。
函数重载是指在同一个作用域内定义了多个同名函数,但是它们的参数类型、个数或顺序不同。在调用这些同名函数时,编译器需要根据传入的参数类型、个数或顺序来确定调用哪一个函数。
使用函数指针可以解决函数重载问题,是因为函数指针是一个指向函数的指针变量,它指向的是函数的入口地址,而不是函数本身。因此,不同的函数可以有不同的入口地址,即使它们的函数名相同。通过定义不同的函数指针类型,可以指向不同的函数,从而实现函数重载的效果。
例如,假设有两个同名函数 foo,一个参数类型为 int,另一个参数类型为 float,可以定义两个不同的函数指针类型,分别指向这两个函数:
void (*foo_int)(int);
void (*foo_float)(float);
然后,根据需要,可以将不同的函数指针指向不同的函数,从而实现函数重载的效果:
void foo1(int x) { … }
void foo2(float x) { … }
foo_int = foo1;
foo_float = foo2;
foo_int(1); // 调用 foo1
foo_float(1.0); // 调用 foo2
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 what);
};
#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:
void hungry();
void hungry(QString what);
public slots:
};
#endif // TEACHER_H
wight.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "student.h"
#include "teacher.h"
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void classIsOver();
private:
Teacher *pTeacher;
Student *pStudent;
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
student.cpp
#include "student.h"
#include <QDebug>
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student::treat()
{
qDebug()<<"Student treat teacher";
}
void Student::treat(QString what)
{
qDebug()<<"Student treat teacher"<<what;
}
teacher.cpp
#include "teacher.h"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
}
wight.cpp
#include "widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//new的时候要加入对象树
//老师和学生的两个对象创建
pTeacher=new Teacher(this);
pStudent=new Student(this);
//建立连接
//两个函数发生了重载
//connect(pTeacher,&Teacher::hungry,pStudent,&Student::treat);
//老师说要吃黄焖鸡,学生就请吃黄焖鸡
//hungry里面多加入一个参数 Qstring类型
//treat里面也需要传入一个参数 Qstring
//因为函数发生了重载 所以要解决
/*
* 1、使用函数指针赋值 让编译器挑选符合类型
* 2、使用static_cast 强制转换,也是让编译器自动挑选符合类型的函数
*/
//传入的是string类型
void (Teacher::*teacher_qString)(QString)=&Teacher::hungry;
void (Student::*student_qString)(QString)=&Student::treat;
connect(pTeacher,teacher_qString,pStudent,student_qString);
//使用static_cast来转换无参的函数
connect(pTeacher,
static_cast <void (Teacher::*)()>(&Teacher::hungry),
pStudent,
static_cast <void (Student::*)()>(&Student::treat));
//下课了
this->classIsOver();
}
void Widget::classIsOver()
{
//触发老师饿了的信号
emit pTeacher->hungry();
//带参数的信号发射
emit pTeacher->hungry("黄焖鸡");
}
Widget::~Widget()
{
}
这里会发生函数重载有二义性 解决方法:
1、使用函数指针赋值 让编译器挑选符合类型
2、使用static_cast 强制转换,也是让编译器自动挑选符合类型的函数
信号和槽的拓展
信号和槽是Qt框架中的两个重要概念,用于实现对象之间的通信。
信号是一个对象发出的消息,表示某个事件已经发生或某个状态已经改变。例如,一个按钮被点击时,它会发出一个clicked()信号。
槽是一个对象的成员函数,用于响应信号。当一个信号被发出时,与之相连的槽函数会被自动调用。例如,一个按钮的clicked()信号可以与一个槽函数相连,当按钮被点击时,槽函数会被调用。
信号和槽之间的关系是通过连接来建立的。
1、一个信号可以连接到多个槽
2、一个槽也可以连接到多个信号。当信号被发出时,所有与之相连的槽函数都会被调用。通过信号和槽的机制,可以实现对象之间的松耦合,使得对象之间的通信更加灵活和可靠。
3、信号是可以连接信号,信号连接信号的语法格式
4、信号可以断开连接 disconnect connect参数怎么填写 那么disconnect的参数就这么填写:
5、信号和槽的关系必须满足以下两点
信号和槽函数的参数类型必须对应
信号和槽函数的参数个数不需要一致,信号函数参数个数>=槽函数参数个数
如果是hungry(int,QString) -> treat(int) ok
qt4的信号与槽
将上面的Widget.cpp中的代码修改一下即可
#include "widget.h"
#include "QPushButton"
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//new的时候要加入对象树
//老师和学生的两个对象创建
pTeacher=new Teacher(this);
pStudent=new Student(this);
//建立连接
//两个函数发生了重载
//connect(pTeacher,&Teacher::hungry,pStudent,&Student::treat);
//老师说要吃黄焖鸡,学生就请吃黄焖鸡
//hungry里面多加入一个参数 Qstring类型
//treat里面也需要传入一个参数 Qstring
//因为函数发生了重载 所以要解决
/*
* 1、使用函数指针赋值 让编译器挑选符合类型
* 2、使用static_cast 强制转换,也是让编译器自动挑选符合类型的函数
*/
//传入的是string类型
//void (Teacher::*teacher_qString)(QString)=&Teacher::hungry;
//void (Student::*student_qString)(QString)=&Student::treat;
//connect(pTeacher,teacher_qString,pStudent,student_qString);
//使用static_cast来转换无参的函数
connect(pTeacher,
static_cast <void (Teacher::*)()>(&Teacher::hungry),
pStudent,
static_cast <void (Student::*)()>(&Student::treat));
//Qt4 的 信号和槽 实现teacher和student带参数的信号和槽连接
connect(pTeacher,SIGNAL(hungry(QString)),pStudent,SLOT(treat(QString)));
//下课了
this->classIsOver();
//QPushButton *btn=new QPushButton("按钮1",this);
//信号可以连接信号
//connect(btn,&QPushButton::clicked,pTeacher,static_cast <void (Teacher::*)()>(&Teacher::hungry));
//信号可以断开连接
//disconnect(btn,&QPushButton::clicked,pTeacher,static_cast <void (Teacher::*)()>(&Teacher::hungry));
}
void Widget::classIsOver()
{
//触发老师饿了的信号
emit pTeacher->hungry();
//带参数的信号发射
emit pTeacher->hungry("黄焖鸡");
}
Widget::~Widget()
{
}
QDebug的输出转义问题
QDebug输出QString默认会转义
what.toUtf8().date():
what
是一个 QString
类型的对象,toUtf8()
是将 QString
对象转换为 QByteArray
类型的对象,date()
是将 QByteArray
对象解析为 QDate
类型的对象。因此,what.toUtf8().date()
的作用是将一个 QString
对象解析为 QDate
类型的对象。
QDebug默认将QString转义输出
解决方法有两个
1 将QString转化为char
2 加入qDebug().noquote()
lambda表达式
在Qt中,mutable
关键字用于修饰类的成员变量,表示该成员变量可以在const
成员函数中被修改。这是因为const
成员函数默认情况下是不能修改类的成员变量的,但是有些情况下我们需要在const
成员函数中修改某些成员变量,这时就可以使用mutable
关键字来修饰这些成员变量。
例如:
class MyClass {
public:
void setValue(int value) const {
m_value = value; // 编译错误,const成员函数不能修改成员变量
m_mutableValue = value; // 正确,mutable成员变量可以在const成员函数中被修改
}
private:
int m_value;
mutable int m_mutableValue;
};
在上面的例子中,m_value
是普通的成员变量,而m_mutableValue
是被mutable
关键字修饰的成员变量。在setValue
函数中,我们试图修改这两个成员变量的值,但是由于setValue
函数是一个const
成员函数,所以只有m_mutableValue
可以被修改。
具体如下:
mutable可以改变拷贝出来的数据,但是改变不了本体的数据
mutable可以改变拷贝出来的数据,但是改变不了本体的数据
** 捕获局部变量分两种方式,一种是值传递,一种是引用传递
&传递可以修改值
默认情况下值传递捕获进来的局部变量就是const
[=] 局部变量全部使用值传递捕获 捕获局部变量包括this
[&] 局部变量全部使用引用传递捕获进来 包括this
=,&bmutable b是引用捕获 其他都是值传递
&,bmutable**
值传递是不能够修改的
connect(btn,&QPushButton::clicked,[=](){
qDebug()<<a<<b;
}); 这里为啥没有槽?
这里使用了lambda表达式作为槽函数,lambda表达式可以在函数内部定义一个匿名函数,可以直接在connect函数中使用,省去了定义槽函数的步骤。在这个例子中,lambda表达式中的[=]表示捕获外部变量a和b的值,使得在lambda表达式中可以直接使用a和b的值。当按钮被点击时,lambda表达式中的代码会被执行。
#include "widget.h"
#include <QDebug>
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
//lambda表达式
//调用lambda的方式,使用函数指针
//第一种方法
// void(*p)()=[]()
// {
// qDebug()<<"Hello lambda";
// };
// p();
//第二种方法
//局部变量捕获
int a=10;
int b=20;
int c=20;
int d=20;
int e=20;
int f=20;
//捕获局部变量分两种方式,一种是值传递,一种是引用传递
//&传递可以修改值
//默认情况下值传递捕获进来的局部变量就是const
//= 局部变量全部使用值传递捕获 捕获局部变量包括this
//& 局部变量全部使用引用传递捕获进来 包括this
//[=,&b]()mutable b是引用捕获 其他都是值传递
//[&,b]()mutable
// [=]()mutable
// {
// qDebug()<<"Hello lambda";
// qDebug()<<a<<b;
// a=20;
// b=30;
// }();
// qDebug()<<a<<b;
//信号和槽的使用(使用lambda)
//以后都使用[=](){}的形式
//不要使用[&](){} 引用传递归根到底还是地址 a b是局部变量 已经释放掉了
QPushButton *btn=new QPushButton("按钮1",this);
connect(btn,&QPushButton::clicked,[=](){
qDebug()<<a<<b;
});
}
Widget::~Widget()
{
}
作业:
在一个窗口写一个open按钮按下去后会显示该窗口下的close按钮和一个新窗口然后点击close会关闭这个窗口