1.1 点击创建项目后,选择项目路径以及 给项目起名
1.2 项目名称不能有中文、空格
1.3 路径不能有中文
2.1 默认创建有窗口类,mywidget, 基类有三种选择:QWidget/ QMainWindow/QDialog
QWidget 是另外两个的基类
#include "mywidget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);//应用程序对象,qt中有且仅有一个QApplication对象
myWidget w; //窗口对象
w.show(); //显示窗口,默认情况下myWidget窗口对象不会自动显示,必须使用show方法
return a.exec(); //阻塞程序,让应用程序对象进入消息循环
}
注释:ctrl + /
运行: ctrl + r
查找: ctrl + f
整行移动: ctrl + shift + ↑或↓
帮助文档: F1 退出帮助文档 :ESC
自动对齐:ctrl + i
#include "mywidget.h"
#include
myWidget::myWidget(QWidget *parent): QWidget(parent)
{
//第一种创建btn的方法
QPushButton *btn1 = new QPushButton;
btn1->show();//show默认以顶层方式弹出窗口(即与当前窗口分离)
btn1->setParent(this);//指定当前btn的父级,(将btn放在当前myWidget窗口内显示)
btn1->setText("first button");
btn1->move(0,0);//移动btn
//第二种方法,QPushbutton类的构造函数有三种重载方法
QPushButton *btn2 = new QPushButton("second button", this);
btn2->move(100,100);
//重置窗口大小
resize(600,400);
//设置固定窗口大小,设置后用户无法改变窗口大小
setFixedSize(600,400);
}
myWidget::~myWidget()
{
}
注意: QT中可以大胆的在堆中创建对象,系统会以对象树的形式帮你自动释放内存,不存在内存泄漏的问题;
窗口左上角为(0,0),X向右增加,Y向下增加,嵌套窗口以其父窗口坐标系为参考系
1. 连接函数: connect
2.connect 的四个参数:
参数1:信号的发出者
参数2:发出的信号(函数地址)
参数3:信号的接收者
参数4:处理的槽函数(函数地址)
3.信号与槽的特点:松散耦合,信号的发出者和信号的接收者原本没有任何关系,通过信号与槽机制(connect)进行耦合
#include "mywidget.h"
#include
myWidget::myWidget(QWidget *parent): QWidget(parent)
{
//第一种创建btn的方法
QPushButton *btn1 = new QPushButton;
btn1->show();//show默认以顶层方式弹出窗口(即与当前窗口分离)
btn1->setParent(this);//指定当前btn的父级,(将btn放在当前myWidget窗口内显示)
btn1->setText("first button");
btn1->move(0,0);//移动btn
//第二种方法,QPushbutton类的构造函数有三种重载方法
QPushButton *btn2 = new QPushButton("second button", this);
btn2->move(100,100);
//重置窗口大小
resize(600,400);
//设置固定窗口大小,设置后用户无法改变窗口大小
setFixedSize(600,400);
//信号与槽,实现点击btn1按钮关闭myWidget窗口
connect(btn1, &QPushButton::clicked,this, &myWidget::close);
}
myWidget::~myWidget()
{
}
目的:不使用系统自带的信号和槽函数,自己定义一个适用于某种特殊情况下的信号和槽函数
业务:当下课铃响起时,学生通知老师下课了,老师布置家庭作业
实现:先创建两个类,class Teacher 、class Student
//Student.h文件
#ifndef STUDENT_H
#define STUDENT_H
#include
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
void class_is_over();//信号函数
};
#endif // STUDENT_H
//Teacher.h文件
#ifndef TEACHER_H
#define TEACHER_H
#include
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
void homeWork(); //槽函数
signals:
};
#endif // TEACHER_H
//student.cpp文件,信号函数不需要具体实现
#include "student.h"
Student::Student(QObject *parent) : QObject(parent)
{
}
//teacher.cpp 槽函数需要具体实现
#include "teacher.h"
#include "QDebug"
Teacher::Teacher(QObject *parent) : QObject(parent)
{
}
void Teacher::homeWork(){
qDebug() << "家庭作业是:背诵课后古诗三首,明天早上来了检查";
}
//myWidget.h 声明一些函数和一些变量
#ifndef WIDGET_H
#define WIDGET_H
#include
#include "QDebug"
#include "student.h"
#include "teacher.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
void bellRings();//声明触发信号的函数
private:
Ui::Widget *ui;
Teacher *ts;
Student *ss;
};
#endif // WIDGET_H
//widget.cpp 具体实现自定义信号与槽的绑定
#include "widget.h"
#include "ui_widget.h"
//业务功能:下课铃响起时,学生向老师发出放学信号,老师布置家庭作业
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->ss = new Student;
this->ts = new Teacher;
//连接信号与槽
connect(ss, &Student::class_is_over, ts, &Teacher::homeWork);
bellRings();
}
Widget::~Widget()
{
delete ui;
}
void Widget::bellRings(){
qDebug()<<"下课铃声响了";
emit ss->class_is_over(); // emit 关键字,用于将ss->class_is_over函数设定为信号函数;
}
注意事项:
自定义信号函数
写在signals下,返回值为void,声明后不需要实现,可以有参数,可以重载
自定义槽函数
写在public或private下都行,返回值为void,声明后需要在.cpp中实现,可以有参数,可以重载
当信号函数或者槽函数重载后,如果不给确定的信号函数和槽函数地址,编译器仅靠函数名是无法分辨该绑定哪个函数,会报错;解决办法是,使用函数指针,指向重载的函数,使用函数指针作为connect函数的参数;
注意:
1.一个信号可以连接多个槽;
2.多个信号可以连接同一个槽
3.信号的参数个数可以多于槽函数的参数个数
3.信号和槽函数的参数个数一致时,类型要一一对应
4.信号可以连接另外一个信号;
5.信号和槽使用disconnect断开连接
#include "widget.h"
#include "ui_widget.h"
//业务功能:下课铃响起时,学生向老师发出放学信号,老师布置家庭作业
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->ss = new Student;
this->ts = new Teacher;
//定义函数指针,分别指向有参的重载函数
void (Teacher:: *p)(QString) = &Teacher::homeWork;
void (Student:: *m)(QString)= &Student::class_is_over;
//将函数指针作为connect函数的参数
connect(ss, m, ts,p);//连接信号与槽
bellRings();
}
Widget::~Widget()
{
delete ui;
}
void Widget::bellRings(){
qDebug()<<"下课铃声响了";
emit ss->class_is_over("语文"); //emit 关键字,用于将ss->class_is_over函数设定为信号函数;
}
//teacher类中重载了homework函数
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
void homeWork();
void homeWork(QString subject);
signals:
};
//student类中重载了class_is_over函数
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
void class_is_over();
void class_is_over(QString b);
};
1.lambda表达式简介
以下内容摘抄自奥修的灵魂的博客lambda表达式详解
lambda表达式又叫做Lambda函数、匿名函数, C ++标准官网展示了一个简单的lambda 表示式实例:
#include
#include
void abssort(float* x, unsigned n) {
std::sort(x, x + n,
// Lambda expression begins
[](float a, float b) {
return (std::abs(a) < std::abs(b));
} // end of lambda expression
);
}
在上面的实例中std::sort函数第三个参数应该是传递一个排序规则的函数,但是这个实例中直接将排序函数的实现写在应该传递函数的位置,省去了定义排序函数的过程,对于这种不需要复用,且短小的函数,直接传递函数体可以增加代码的可读性。
auto function = [] (int first, int second){
return first + second;
};
function(100, 200);
[]标识符,捕获列表,可以使用
=(值传递,捕获作用域内所有的变量)、
&(引用传递,捕获作用域内所有变量)、
a(a代表作用域内的某个具体的变量)、
&a;
()参数
{ } 实现体
-> 返回值类型
int a(5),b(6);
int ret = []()->int{ returen a+b; }
mutable 修饰值传递变量,可以修改变量的拷贝值,不能修改本身