1.QPushBotton 以及 对象树
目录
1. 创建第一个Qt程序
1.1 初始化设置
🍐 选择存储位置
🍊 Kit
🍋 类信息
🍌 项目管理
1.2 代码
🍉 main.cpp
🍇widget.h
🍓 widget.cpp
1.3 .pro文件
🍈 常见模块
编辑
2. 命名规范以及快捷键
2.1 类名:
2.2 函数名 变量名称:
2.3 快捷键
3. QPushBotton 按钮
3.2. 那怎么添加到原始界面中呢?
编辑
3.3. 设置按钮上的显示文本
3.4. 以其他函数重载的形式创建按钮
3.5. 我们可以将第二个按钮挪一个位置,移动控件
3.6. 修改窗口标题
3.7. 设置固定窗口大小
4. 对象树
4.1. 什么是对象树,它有什么作用呢?
4.2. 对象树上的对象构造和析构顺序
4.3. 坐标系
参考
1. 创建第一个Qt程序
1.1 初始化设置
🍐 选择存储位置
🍊 Kit
构建套件
🍋 类信息
QMainWindow、QDialog、QWidget之间的关系
- QWidget 一个自由的窗口类自己添加
- QMainWindow:有和Qt界面类似的菜单界面
- QDialog: 有默认的窗口类
🍌 项目管理
1.2 代码
🍉 main.cpp
#include "widget.h"#include <QApplication> //包含一个应用程序的类//main程序入口 argc命令行变量的数量 argv命令行变量的数组
//argc,argv将电脑中的获取各种操作指令,即把不同的命令行内容传递给main函数
int main(int argc, char *argv[])
{//此处argc,argv将电脑的指令传给a对象//a为应用程序对象,在Qt中应用程序对象 有且只有一个QApplication a(argc, argv);//窗口对象 Widget父类为QWidgetWidget w;//窗口对象 默认不会显示 必须要调用show方法显示窗口w.show();//让应用程序对象进入到消息循环机制,一直在捕捉动作//可以等价为一个死循环,一直在等待客户动作//让代码阻塞到这行return a.exec();
}//return a.exec();等价为如下的死循环
//一直在执行,只有点击叉子才会跳出
//while(treue)
//{
// if(点击叉子){break;}
//}
🍇widget.h
#ifndef WIDGET_H //避免头文件重复包含 没有定义的话就定义
#define WIDGET_H#include <QWidget> //包含一个窗口的头文件 QWidget 窗口类class Widget : public QWidget
{//Q_OBJECT宏 允许类中使用信号和槽的机制 但是怎么通过宏控制的呢Q_OBJECTpublic:Widget(QWidget *parent = nullptr);//构造函数~Widget();//析构
};
#endif // WIDGET_H
🍓 widget.cpp
#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) //初始化列表,在.h文件中parent值为nullptr
{
}Widget::~Widget()
{
}
1.3 .pro文件
相当于编辑的makefile文件,Qt会自动编写。
QT += core gui //QT包含的模块,还有sql等等
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
//这里大于4以上的版本才需要,用来表示联合之前的应用
TARGET = Demo2 //生成exe目标程序的程序名
TEMPLATE = app //应用程序模板 application
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \main.cpp \mywidget.cpp //添加源文件HEADERS += \ //头文件mywidget.h
🍈 常见模块
2. 命名规范以及快捷键
2.1 类名:
首字母大写,单词和单词之间首字母大写
如:TeamMake
2.2 函数名 变量名称:
首字母小写,单词和单词之间首字母大写
2.3 快捷键
- 查找 Ctrl + f
- 运行 Ctrl + r
- 编译 Ctrl + b
- 多重注释 Ctrl + /
- 自动对齐 Ctrl + i
- 帮助文档 F1
- 同名之间.h 以及 .cpp切换 F4
3. QPushBotton 按钮
3.1. 创建一个pushbutton
需要使用到QPushButton类,在widget.cpp中添加如下:
#include "widget.h"
#include <QPushButton> //按钮控件的头文件Widget::Widget(QWidget *parent): QWidget(parent) //初始化列表,在.h文件中parent值为nullptr
{//创建一个按钮QPushButton* btn=new QPushButton;btn->show();//显示button,show()函数继承自widget类中
}
运行之后会发现:我创建的pushbutton没有附加到原始的界面中。
这是因为show()是将界面以顶层方式弹出窗口控件。一般不使用
3.2. 那怎么添加到原始界面中呢?
//创建一个按钮QPushButton* btn=new QPushButton;//让btn对象依赖在主界面中,即使指针指向当前的对象btn->setParent(this);//this指向的即为当前对象指针
运行结果:
3.3. 设置按钮上的显示文本
//创建一个按钮QPushButton* btn=new QPushButton;//让btn对象依赖在主界面中,即使指针指向当前的对象btn->setParent(this);//this指向的即为当前对象指针//设置按钮上显式的文字btn->setText("第一个按钮");
3.4. 以其他函数重载的形式创建按钮
注释掉前面第一个按钮的代码后添加如下代码:
//创建第二个按钮,按照控件大小创建窗口QPushButton* btn2=new QPushButton("第二个按钮",this);
这个时候我们可以重载窗口大小
//重置窗口大小
resize(600,400);
3.5. 我们可以将第二个按钮挪一个位置,移动控件
//移动第二个按钮
btn2->move(100,100);
3.6. 修改窗口标题
//设置窗口标题
setWindowTitle("第一个窗口");
3.7. 设置固定窗口大小
这样窗口大小就不可以手动的放大缩小了
//设置固定的窗口大小
setFixedSize(600,400);
4. 对象树
4.1. 什么是对象树,它有什么作用呢?
简单一些总结: 当创建的对象在堆区时候,如果指定的父亲是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作,对象会放入到对象树中。一定程度上简化了内存释放的过程。
在创建QObject对象时,可以提供一个其父对象,我们创建的这个QObject对象会自动添加到其父对象的children()列表。当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类!)
Qt 引入对象树的概念,在一定程度上解决了内存问题。
当一个QObject对象在堆上创建的时候,Qt 会同时为其创建一个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。
任何对象树中的 QObject对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的children()列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有QObject会被 delete 两次,这是由析构顺序决定的。
如果QObject在栈上创建,Qt 保持同样的行为。正常情况下,这也不会发生什么问题。
对象树模型:
4.2. 对象树上的对象构造和析构顺序
从上对象树中可以看到,构造是从上往下的,析构是从下往上的。
下面利用代码进行析构顺序的演示
(1)添加自定义类
(2)对继承的父类进行修改,得到如下:
mypushbutton.h
#ifndef MYPUSHBUTTON_H
#define MYPUSHBUTTON_H#include <QPushButton>class MyPushButton : public QPushButton
{Q_OBJECT
public:explicit MyPushButton(QWidget *parent = nullptr);signals:};#endif // MYPUSHBUTTON_H
mypushbutton.cpp
#include "mypushbutton.h"MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
{}
创建构造和析构函数
MyPushButton中的构造析构分别添加qDebug命令
MyPushButton::MyPushButton(QWidget *parent) : QPushButton(parent)
{
qDebug()<<"111";
}
MyPushButton::~MyPushButton()
{
qDebug()<<"222";
}
Widget中添加如下:
Widget::~Widget()
{
qDebug()<<"333";
}
运行之后可以看到:
111 //MyPushButton构造
333 //Widget析构
222 //MyPushButton析构
按照之前的理论,好像不是按照从下往上进行析构的,这是为什么呢?
这里给出答案,这是因为析构时,先走到Widget的析构函数,先将析构函数内的命令执行,然后才会看Widget是否有子类,如果有子类就执行子类的析构函数。
4.3. 坐标系
以左上角为原点(0,0),X向右增加,Y向下增加。
参考
04 创建第一个Qt程序_哔哩哔哩_bilibili
QT从入门到实战x篇_04_对象树及坐标系_qt对象树析构顺序-CSDN博客