QT传智版笔记-day01

QT传智版笔记-day01

#include "mainwindow.h"

#include <QApplication>//包含一个应用程序的头文件

//main程序入口 argc 命令行变量的数量 argv命令行变量的数组
//一个程序界面鼠标点了 键盘键入的数据都是由下面这两个参数进行传入的
int main(int argc, char *argv[])
{
    //接收到界面的鼠标 键盘键入命令后将这些命令放入这个方法的参数中
    //a就是应用程序对象 在QT中,应用程序对象有且只有一个
    QApplication a(argc, argv);

    //窗口对象 myWidget父类 ->QWidget
    MainWindow w;
    //窗口对象,默认不会显示,必须要调用show方法显示窗口
    //当代码阻塞到这里
    w.show();

    //让应用程序对象进入消息循环机制 差不多就是个死循环,直到
    return a.exec();
}

QT += core gui QT包含的模块 core:核心 gui:图形
greaterThan(QT_MAJOR_VERSION,4): QT += widgets //大于4版本以上 包含widget模块

TARGET = 01_FirstProject	//目标  生成.exe程序的名称
TEMPLATE = app 				//模板 应用程序模板 Application

SOURCES += main.cpp\		//源文件
		mywidget.cpp
HEADERS += mywidget.h		//头文件

构造函数与析构函数

特殊函数:由系统自动指向,在程序中不可显式地调用它们。

  • 构造函数的作用:建立对象时对对象的数据成员进行初始化
  • 析构函数的作用:对象生命周期结束时回收对象
    • 构造函数:对象的初始化
    • 析构函数:回收/撤销对象 回收分配的空间
  • 构造函数和析构函数是一一对应的

构造函数:对象初始化

  • 构造函数的作用:建立对象时对对象的数据成员进行初始化
  • 是与类同名的特殊成员函数
  • 没有返回值
  • 可以有多个,带参数及无参数均可。
  • 构造函数没有返回值但是不需要写void

复习重载:同名的函数 参数不同叫做重载。

无参构造函数 对象的初始化

例10.2 用class定义一个学生类,并在主函数中定义类的对象进行调用测试。

class student
{
	private:
		int no;
		string name;
		float score[3];
	public:
		student();	//构造函数
		void display();//定义略
};

student :: student()	//:: 这两个冒号表示 前面的student这个类 归属于后面的student()函数
{
	no = 0;
	name="null";
	for(int i = 0;i<3;i++)
	score[i] = 0;
};

int main(){
	student s1;
	s1.display();
	return 0;
};
class student{
	private:
    	int no;
    	string name;
    	float score[3];
    public:
    	student(int n,string na,float s[3]);
    	void display();//定义略
};

student :: student(int n,char na[20],float s[3]){
    no=n;
    name = na;
    for(int i = 0;i<3;i++) 
        score[i]=s[i];
}

int main(){
    float s[3]={93,89,87};
    student s1(100,"zhou",s);
    s1.display();
    return 0;
}

默认构造函数 对象的初始化

  • C++ 规定,每个类必须有构造函数
  • 如果一个类没有定义任何构造函数,在需要时编译器将会为它生成一个无参的,函数体为空的默认构造函数
  • 默认构造函数只是在形式上保证创建对象时必须有构造函数。
  • 一旦写了一个构造函数,系统就不再提供默认的构造函数

构造函数的特点

  • 构造函数与类同名
  • 构造函数没有返回类型
  • 构造函数由系统自动调用,不允许在程序中显式调用。
  • 构造函数可以被重载,即一个类可以定义多个参数或参数类型不同的构造函数
class student{
	private:
		int no;
		string name;
		float score[3];
	public:
		studnet();//无参
		student(int n,string na,float s[3]);//有参
		void display();
};

析构函数-回收/撤销对象

  • 析构函数主要用于对象生命周期结束时回收对象
  • 与类同名,在其前面加上字符"~"
  • 没有返回值
  • 在一个类当中只有一个,无参
//类内声明:
class X{
	......
	~X();
	......
};

//类内定义
class X{
	......
	~X(){}
	......
};

析构应用

class student //定义学生类,有构造函数和析构函数
{
 	private:
    	int no;
    	string name;
    	float score[3];
    public:
    	student();//无参构造函数,类外定义
    	student(int n,string na,float s[3]);//有参构造函数,类外定义
    	~student()
        {cout<<"destroy.\n"}//析构函数,可以在类内定义
    void display();
};

//对无参构造函数的定义
student :: student(){
    no = 0;
    name = "null";
    for(int i = 0; i<3; i++)score[i]=0;
}
//对有参构造函数的定义
student :: student(int n,string na,float s[3]){
    no = 0;
    name = "null";
    for(int i = 0; i<3; i++)score[i]=s[i];
}
//对display函数的定义
//信息的输出 把display放在类的外面 放在类的外面需要指明它的归属程度
void student :: display() //类名写在哪里才能表明函数归属于哪一个类
{
    cout<<no<<"\t"<<name<<"\t";
    for(int i = 0; i<3;i++)
        cout<<score[i]<<"\t";
    cout<<end1;
}

例10.2用class定义一个学生类,并在主函数中定义类的对象进行调用测试

int main(){
	float s[3] = {93,89,87};
	student s1,s2(100,"zhou",s);
	s1.display();
	s2.display();
	return 0;
}

默认析构函数

  • 如果一个类没有定义任何析构函数,系统会为它生成一个默认析构函数。
  • 对应大多数类,默认析构函数能够满足要求。
  • 只有在一个对象完成其操作之前需要做一些内部处理时,才显示地定义析构函数
class X{
	......
	~X(){}
	......
};
student :: ~student(){
	cout<<"destroy\n";
}

第一个按钮

#include "mywidget.h"
#include <QPushButton> //按钮控件的头文件

//命名规范
//类名 首字母大写,单词和单词之间首字母大写
//函数名 变量名称 首字母小写,单词和单词之间首字母大写

//快捷键
//注释 ctrl + /
//运行 ctrl + r
//编译 ctrl + b
//字体缩放 ctrl + 鼠标滚轮
//查找 ctrl + f
//整行移动 ctrl + shift + ↑ 或者 ↓
//帮助文档 F1
//自动对齐 ctrl = i;
//同名之间的.h 和 .cpp切换 F4

//帮助文档    第一种方式F1
//          第二种方式 左侧按钮
//          第三种方式 ?:\Qt\qtxx.x.x\x.x\mingw49_32\bin

myWidget::myWidget(QWidget *parent)
    : QWidget(parent)       //初始化列表
{
    //创建一个按钮 先引入按钮头文件
    QPushButton * btn = new QPushButton;
    //注意:show默认是在顶层窗口展示,也就是一个独立的自己的窗口,要归属于另一个窗口需要进行
//    btn->show();//show以顶层方式弹出窗口控件
    //需求是让btn对象,依赖在 myWidget窗口中
    //设置”父亲“ 把父亲myWidget的指针放入参数中用this this指向当前对象的指针
    btn->setParent(this);

    //显示文本
    btn->setText("第一个按钮");

    //创建第二个按钮 按照空间的大小创建窗口 而且默认会覆盖上面的按钮 需要移动位置


    QPushButton * btn2 = new QPushButton("第二个按钮",this);//效果与上面的相同
    //移动btn2按钮
    btn2->move(100,100);

    //重置窗口大小 resize在stl中是重置内存大小
    resize(600,400);

    //对按钮大小进行调整
    btn2->resize(50,50);

    //设置窗口标题
    setWindowTitle("第一个窗口");//但是此时可以缩放窗口
    setFixedSize(600,400);


}

myWidget::~myWidget()
{
}


对象树

在Qt中创建对象的时候会提供一个Parent对象指针,下面来解释一下这个parent到底是干什么的。

  • QObject是以对象树的形式组指起来的。

    • 当你创建一个QObject对象时,会看到QObject的构造函数接收一个QObject指针作为参数,这个参数就是parent,也就是父对象指针。

    这相当于,在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。

    • 当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意思上的父类!)

    这种机制在GUI程序设计中相当有用。例如,一个按钮有一个QShortcut(快捷键)对象作为其子对象。当我们删除按钮的时候,这个快捷键理应被删除。这是合理的。

  • QWidget是能够在屏幕上显示一切组件的父类。

    • QWidget继承自QObject,因此也继承了这种对象树关系。一个孩子自动地成为父组件的一个子组件,因此,它会显示在父组件的坐标系中,被父组件的边界剪裁。例如用户关闭一个对话框的时候,应用程序将其删除,那么,我们希望属于这个对话框的按钮、图标等应该一起被删除。事实就是如此,因为这些都是对话框的子组件。

QT的窗口原点在 0.0点 不同引擎的窗口起始点是不一样的。

信号和槽

人 -----摩擦摩擦 ------ 神灯------ 出神灯

按钮 ------ 点击 ------ 窗口 ------ 关闭窗口

connect(信号的发送者,发送的具体信号,信号的接收者,信号的处理(槽))
信号槽的优点,松散耦合,信号发送端 和 接收端 本身是没有关联的,通过connect连接 将两端耦合在一起
    //需求:点击我的按钮,关闭窗口
    //参数1 信号的发送者 参数2 发送的信号(函数的地址) 参数3 信号的接收者 参数4 处理的槽函数
    connect(myBtn,&QPushButton::clicked,this, &QWidget::close);
    connect(myBtn,&MyPushButton::clicked,this, &myWidget::close);

拓展

1、信号是可以连接信号的

2、一个信号可以连接多个槽函数

3、多个信号,可以连接同一个槽函数

4、信号和槽的参数 必须类型一一对应

5、信号和槽的参数个数是不是要一致?信号的参数个数 可以多于槽函数的参数个数

利用QT4信号槽 连接无参版本

connect(zt,SIGNAL(hungry()),st,SLOT(treat()));

QT4版本有点:参数只管,缺点:类型不做检测

Lambda表达式

C++中的Lambda表达式用于定义并创建匿名的函数对象,以简化编程工作,首先看一下Lambda表达式的基本构成:

[capture](parameter) mutable->return-type
{
	statement
}

[函数对象参数] (操作符重载函数参数) mutable -> 返回值(函数体)

  • 函数对象参数;

[],标识一个 Lambda的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数的。函数对象参数只能使用那些到定义Lamb大为止时Lambda所在作用范围内可见局部变量(包括Lambda所在类的this)。函数对象参数有一下形式:

  • 空。没有使用任何函数对象参数
  • =。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且时值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。
  • &。函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。
  • this。函数体内可以使用Lambda所在类中的成员变量。
  • a。将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数时const的。要修改传递进来的a的拷贝,可以添加mutable修饰符
  • &a。将a按引用进行传递。
  • a,&b。将a按值进行传递,b按引用进行传递
  • =,&a,&b 除a和b按引用进行传递外,其他参数都按值进行传递
  • &,a,b。除a和b按值进行传递外,其他参数都按引用进行传递

操作符重载函数参数:

  • 标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过值(如:(a,b)和按引用(如:(&a,&b)))两种方式进行传递

可修改标识符:

  • mutable声明,这部分可以省略。按值传递函数对象参数时,加上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(myBtn,&QpushButton::clicked,this,[=]() {qDebug() << m;});
qDebug() << m;

函数返回值;

->返回值类型,标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此编译器可以自动推断出返回值类型)时这部分可以省略。

时函数体:

{},标识函数的实现,这部分不能省略,但函数体可以为空

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值