Qt入门教程---项目创建全过程内存泄漏解释

目录

1.创建项目的说明

2.代码介绍说明

2.1文件分类介绍

2.2sources文件

2.3widget.ui文件

2.4widget.h文件

2.5中间文件

2.6.pro文件

3.打印输出hello world

3.1图形化界面生成控件

3.2代码生成控件

3.3打印结果展示

4.对于内存泄露的讨论

4.1对象树

4.2与栈开辟空间的对比

4.3展示对象树释放对象的过程

4.4自定义类的设计

4.5我的总结

5.乱码问题的解释

5.1对于字符编码方式认识

5.2qDebug认识

5.3修改运行


1.创建项目的说明

之前的这个教程里面已经介绍了这个qt里面的项目的创建过程以及创建出来的这个代码的一些说明

我们当时进行这个项目的创建的时候,这个里面的默认的这个配置(information即下面的这个配置页面),这个里面的默认的选项是windows之类的,我们这个时候点击下拉框,把这个改成wight这个选项,我们前期都是使用的这个选项进行项目的创建;

2.代码介绍说明

2.1文件分类介绍

在一个简单生成的这个qt项目文件里面,其实这个里面的文件的内容还是蛮多的,我们只需要大致了解即可,很多文件是自动生成创建的,需要我们手动写的代码还是在一些主要的文件里面;

除了这个主要的文件之外,其他的这个文件就是自动生成创建的,了解即可;

2.2sources文件

  • 我们的这个示例代码就是包含了;两个头文件,使用这个main函数进行程序的编写,qapplication就是使用这个已知的类去创建一个对象a,这个其实就是执行的构造函数,argc和argv就是我们的这个命令行参数;
  • widgit就是创建一个对象w,w其实就是一个控件对象,show函数的调用就是让这个控件给显示出来
  • return里面的这个方法的调用目的就是让这个程序运行起来即可;

2.3widget.ui文件

这个文件我们双击之后就会跳转到下面的这个页面:这个是qt designer的页面,这个是一个图形化的页面,左边的是qt里面的内置的空间,直接拖拽控件就可以进行创建项目界面

我们在重新回到这个ui文件,就可以看到下面的这个代码的格式,这个其实就是xml类型的代码,和我们熟悉的这个html世纪上是很相似的,这个里面也有这个标签之类的定义,这个xml实际上就是为了把我们的这个文件生成c++代码,从而进一步把这个完整的界面构造出来;

2.4widget.h文件

这个文件里面的内容就是我们对于这个widget的相关的声明;

上面的这个ifndef这些就是保证我们的头文件只包含一次,建议使用#pragme once让这个文件只会包含一次;

这个代码里面也可以看出来,这个widget继承自父类Qwidget,这个父类是内置的,想要使用就要包含对应的头文件,这个里面的第四行代码就是为了包含这个对应的头文件;但是也不是所有的情况下都需要包含头文件,可能需要间接包含也是可以被允许的;

上面这个代码里面的14行里面的这个东西实际上是我们的qt里面的一个宏,qt里面有一个很重要的机制:信号和槽,需要使用这个机制的时候就需要包含这个宏,这个宏和信号槽有关联;

最下面的就是这个构造函数和析构函数的调用过程,15行的这个括号里面的参数是qt里面的对象数机制,用来表明我们的这个对象数是谁;

2.5中间文件

这个文件夹路径里面会有这个我们自己创建的项目文件,上面的两个文件就是我们的这个中间文件

具体的内容就是一些生成的这个临时文件,里面的这个makefile文件是自动生成的,不需要我们自己去手写文件;

这个里面的exe就是可执行程序,和我们点击qt里面的这个运行按钮看到的效果是一样的;

2.6.pro文件

第一行就是引入一些模块,我们后面如果有需要也是可以进行修改的;

18-20就是描述编译器需要进行编译的文件有哪些,这个我们不需要管;

pro文件类似于我们的这个makefile文件,指明了这个编译的方法,进行编译的文件和编译之后生成的文件,qt creater把这个编译的细节都封装好了,我们直接点击这个运行按钮就可以了;

3.打印输出hello world

如何打印输出hello world这个内容,基本上是我们在学习所有的编程语言入门的时候都会经历的一个环节,这个qt的学习也不会例外,下面我们会介绍在qt creater里面打印这个hello world的两个方式,本质都是生成控件,一个是使用的图形化界面的方式生成控件,还有一个就是通过代码生成这个控件;

3.1图形化界面生成控件

进入这个qt designer里面:在这个窗口里面点击ui文件就会跳转到我们的这个designer里面去;

在这个里面,我们使用图形化界面的方式生成这个效果,就需要使用这个label标签,我们把这个拖到这个幕布上面去,就是点击这个label拖到这个画布上面,拖动过去之后的大小其实是可以进行修改的,我们通过拉拽的方式就可以对于这个拖动之后的这个标签的大小进行放大或者是缩小;

然后双击这个标签,就可以对于这个内容进行修改,我们就可以把这个hello world内容写到这个画布上面去,点击运行,这个时候会提示我们是否保存修改,我们直接点击save all即可,就是保存所有的修改的意思;

和之前的图形化页面相比较,我们就会发现这个ui文件里面的这个xml内容实际上就多了我们写了这个hello world的相关的配置内容;

3.2代码生成控件

这个时候我们不可以直接创建,而是把上面的那个使用图形化界面生成控件的项目关闭掉,之后再去创建新的文件来编写我们的代码生成控件;

下面的这个就是我们的代码,就是主要在widget.cpp文件里面操作的,主要是在这个cpp文件里面的构造函数中添加内容,下面我将对于代码进行详细说明:

  1. 我们需要使用new方法创建一个对象出来,这个对象我们命名为label,且它的类型是QLabel*类型的;
  2. 这个QLabel类型的使用需要包含对应的头文件,即include<Qlabel>这个里面在包含的时候会 有Qlabel.h文件的提示,这个我在注释里面进行了说明,实际上就是当时的c++不是很完善,qt自己设计了一套方法使用,保证不会出问题;
  3. 这个new对象的时候,里面的参数需要加上这个this,这个原有的代码里面也是有这个this的;
  4. label->setText就是显示控件里面的文本的内容,对应的方法参数就是我们的内容hello world;
  5. setText函数参数实际上是一个Qstring类型的对象,这个我们可以像下面一样隐式的写,也可以写做这个Qstring("hello world")进行表示,就算我们直接写,qt也是可以自动进行转换的;

3.3打印结果展示

打印结果显示:下面的这个使用代码生成的是直接把这个显示在我们的左上角,如果是使用label拖拽的方式的话,就是显示在我们的拖拽的那个位置,这个是可以进行修改的;

4.对于内存泄露的讨论

4.1对象树

可能细心的同学已经看到了这个问题,就是内存泄露的问题,我们上面使用这个new创建对象,但是却没进行delete操作,按理说就存在内存泄露的风险,但是这个运行的时候没有遇到问题,这个其实就是因为我们把这个对象挂到了对象树上面去;

下面的这个就是一个简单的对象树,这个对象树最主要的作用就是为了能够在合适的时机,把我们自己创建的对象统一释放掉,对象树管理这些对象,因此这个时候没有出现内存泄漏的问题;

4.2与栈开辟空间的对比

我们上面的这个是使用的new开辟空间的,这个也可以直接在栈上面开空间,即QLabel label进行对象的创建,这个时候我们的label就不是一个指针了,因此我们需要使用这个label.setText进行这个函数的调用,这个时候依然是可以运行的,但是没有这个结果的打印输出;

这个就是因为我们在栈上面开空间的时候,我们的创建的对象就不是交给对象树进行管理的,因此这个时候对于对象的释放就出现了问题,这个时候的打印结果无法正常输出,这个也是我们为什么使用new创建对象的原因;

4.3展示对象树释放对象的过程

我们上面是自己创建的这个label对象,我们想要看到这个对象树释放对象的过程,就需要我们自己独立去实现一个类,看看会不会调用这个里面的析构函数;

就是我们原来是使用的系统的类创建对象,现在我们自己实现这个过程,看看会不会达到相同的效果;

在qt creater里面,我们自己如何创建一个类呢,按照下面的这个过程尝试一下吧:这个也会加深我们对于内存泄漏的理解深度~~

首先点击这个工具栏的文件里面的新建文件:

选择这个c++文件,右边就为我们默认匹配这个c++ class文件,直接创建:

这个时候,我们需要填写这个类的名字,因为我们的这个类是自己创建的,我们就可以取名字为mylabel,下面让我们选择这个base class也就是基础类,实际上就是我们自定义的这个类的父类,我们选择这个QLlabel(就是之前包含的那个头文件,这个是系统自带的),注意这个QLabel里面的这个前面的两个字符都是大写的,这个一定不要搞错了;

我们选择的时候发现没有,这个时候我们就在第三个框框里面去自己写上去就可以了,这个里面还为我们用户提供了一些头文件,我们不用管就好了,就算用到了,我们自己也是可以手动包含的;

接下来的这个就是确认我们的文件的生成的位置,这个也是选择默认的就行,直接点击完成:

完成之后我们就会发现这个文件目录里面多了我们自己创建的这个mylabel的.h文件和.cpp文件,这个就表明我们上面的创建的过程是成功的;

4.4自定义类的设计

对于新的.h文件的修改:可以在这个构造函数里面添加上我们的parent,是QWidget*类型的,这样做的目的就是把新创建的对象添加到这个对象树上面去,因为我们的这个父类在对象树上面,我们的自定义类继承自这个父类,就可以挂在这个对象树上面了;

下面的这个是在.cpp文件里面的修改的过程,我们可以使用这个F4直接切换到这个.h对应的这个.cpp文件里面去,比较迅速~~

mylabel就是我们自己创建的一个类,继承自父类parent,是QWidget*类型的父类,这几个类型之间的关系一定要捋清楚了;Qlabel是系统的这个自带的类,我们实现的就是一个类似的这个功能,只不过是我们自己定义的,因此取名字为mylabel;

接下来,我们就是在这个mylabel里面添加上这个析构函数,打印输出一句话:

上面进行的操作,都是在创建类,我们还没进行对象的创建,我们需要在这个widget文件里面进行这个对象的创建工作;创建的方法就是用的new,和上面没有什么区别;

这个时候保存所有文件,点击运行,这个时候打印了这个hello world,怎么看到这个析构函数执行时候的日志的输出文件呢,实际上,我们可以使用这个找到这个下面的应用程序输出,这个时候,我们把这个hello world输出的这个框框叉掉,这个时候我们的日志就会被打印出来了;

但是这个里面出现了乱码,我们下面会介绍一下这个解决方案;

4.5我的总结

其实对于这个自定义类和对象的这个过程,对于初学者而言肯定是有些许复杂的,不同文件之间的切换以及这个构造函数,析构函数,继承关系的调整都是我们需要注意的;

首先,我们的这个QLabel是系统自带的,我们想要看看自己实现一个类似于这个QLabel会不会执行这个析构函数,因为我们使用这个QLabel创建对象的时候,这个析构函数的执行过程我们是看不到的,我们想要确认一下这个析构函数的执行的过程,因此我们自己定义了一个mylabel的类,这个类继承自QWidget*类型的 parent的父类,这个是我们的整体逻辑和思路;

接下来才是去写使用我们自定义的类创建对象,然后去写这个析构函数,打印输出日志等操作;

5.乱码问题的解释

5.1对于字符编码方式认识

我们目前的主流的编码方式就是GBK和utf-8,我们的这个文件里面的这个代码的编码方式就是utf-8,但是这个qt creater里面的这个终端的编码方式和utf-8不同,因此出现了这个乱码的情况;

5.2qDebug认识

我们上面是使用的这个cout打印输出的,出现了这个乱码的问题,我们使用这个qt里面自带的这个qdebug进行打印就可以让这个系统自动调整编码的相关设置,帮助我们解决乱码的问题;

5.3修改运行

加上这个头文件,使用这个qdebug()打印输出这个调试的日志,就可以解决这个乱码的问题;

qdebug可以通过设置开关,实现对于这个发布和调试过程中是否有这个日志的控制,是有好处的~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/876263.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一图读懂 若依后端

一图读懂 若依后端 关注我&#xff0c;评论区评论就能获得思维导图本体文件啦&#x1f604;。如果你愿意关注我的掘金就更好啦宝&#x1f60d;&#xff0c;因为我掘金文章就一内内人看&#xff0c;想引流&#x1f60b; https://juejin.cn/user/1942157160101860本图是对若依后…

基础GAN生成式对抗网络(pytorch实验)

&#xff08;Generative Adversarial Network&#xff09; 一、理论 https://zhuanlan.zhihu.com/p/307527293?utm_campaignshareopn&utm_mediumsocial&utm_psn1815884330188283904&utm_sourcewechat_session 大佬的文章中的“GEN的本质”部分 二、实验 1、数…

Java | Leetcode Java题解之第403题青蛙过河

题目&#xff1a; 题解&#xff1a; class Solution {public boolean canCross(int[] stones) {int n stones.length;boolean[][] dp new boolean[n][n];dp[0][0] true;for (int i 1; i < n; i) {if (stones[i] - stones[i - 1] > i) {return false;}}for (int i 1…

Oracle 11gR2打PSU补丁详细教程

1 说明 Oracle的PSU&#xff08;Patch Set Update&#xff09;补丁是Oracle公司为了其数据库产品定期发布的更新包&#xff0c;通常每季度发布一次。PSU包含了该季度内收集的一系列安全更新&#xff08;CPU&#xff1a;Critical Patch Update&#xff09;以及一些重要的错误修…

效率神器来了:AI工具手把手教你快速提升工作效能

随着科技的进步&#xff0c;AI工具已经成为提升工作效率的关键手段。本文将介绍一些实用的AI工具和方法&#xff0c;帮助你自动化繁琐的重复性任务、优化数据管理、促进团队协作与沟通&#xff0c;并提升决策质量。 背景&#xff1a;OOP AI-免费问答学习交流-GPT 自动化重复性任…

【Linux】【Vim】Vim 基础

Vim/Gvim 基础 文本编辑基础编辑操作符命令和位移改变文本重复改动Visual 模式移动文本(复制、粘贴)文本对象替换模式 光标移动以 word 为单位移动行首和行尾行内指定单字符移动到匹配的括号光标移动到指定行滚屏简单查找 /string标记 分屏vimdiff 文本编辑 基础编辑 Normal 模…

【网络安全的神秘世界】渗透测试基础

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 渗透测试基础 基于功能去进行漏洞挖掘 1、编辑器漏洞 1.1 编辑器漏洞介绍 一般企业搭建网站可能采用了通用模板&#xff…

app抓包 chrome://inspect/#devices

一、前言&#xff1a; 1.首先不支持flutter框架&#xff0c;可支持ionic、taro 2.初次需要翻墙 3.app为debug包&#xff0c;非release 二、具体步骤 1.谷歌浏览器地址&#xff1a;chrome://inspect/#devices qq浏览器地址&#xff1a;qqbrowser://inspect/#devi…

Lombok:Java开发者的代码简化神器【后端 17】

Lombok&#xff1a;Java开发者的代码简化神器 在Java开发中&#xff0c;我们经常需要编写大量的样板代码&#xff0c;如getter、setter、equals、hashCode、toString等方法。这些代码虽然基础且必要&#xff0c;但往往占据了大量开发时间&#xff0c;且容易在属性变更时引发错误…

华为OD机试 - 计算误码率(Python/JS/C/C++ 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试真题&#xff08;Python/JS/C/C&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加入华为OD刷题交流群&#xff0c;…

怎么将几个pdf合成为一个?把几个PDF合并成为一个的8种方法

怎么将几个pdf合成为一个&#xff1f;将多个PDF文件合并成一个整体可以显著提高信息整合的效率&#xff0c;并简化文件的管理与传递。例如&#xff0c;将不同章节的电子书合成一本完整的书籍&#xff0c;或者将多个部门的报告整合成一个统一的文档&#xff0c;可以使处理流程变…

CCS811二氧化碳传感器详解(STM32)

目录 一、介绍 二、传感器原理 1.原理图 2.引脚描述 3.工作原理介绍 三、程序设计 main.c文件 ccs811.h文件 ccs811.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 CCS811模块是一种气体传感器&#xff0c;可以测量环境中TVOC(总挥发性有机物质)浓度和eCO2…

6.接口测试加密接口(Jmeter/工具/函数助手对话框、Beanshell脚本)

一、接口测试加密接口&#xff0c;签名接口 1.加密算法&#xff1a; 可以解密的&#xff1a; 对称式加密&#xff08;私钥加密&#xff09;&#xff1a;AES&#xff0c;DES&#xff0c;Base64 https://www.bejson.com 非对称加密&#xff08;双…

Fisco Bcos 2.11.0通过网络和本地二进制文件搭建单机节点联盟链网络(搭建你的第一个区块链网络)

Fisco Bcos 2.11.0通过网络和本地二进制文件搭建单机节点联盟链网络(搭建你的第一个区块链网络) 文章目录 Fisco Bcos 2.11.0通过网络和本地二进制文件搭建单机节点联盟链网络(搭建你的第一个区块链网络)前言一、Ubuntu依赖安装二、创建操作目录, 下载build_chain.sh脚本2.1 先…

Linux-Swap分区使用与扩容

一、背景 在Linux系统中&#xff0c;swap空间&#xff08;通常称为swap分区&#xff09;是一个用于补充内存资源的重要组件。当系统的物理RAM不足时&#xff0c;Linux会将一部分不经常使用的内存页面移动到硬盘上的swap空间中&#xff0c;这个过程被称为分页&#xff08;paging…

【JavaEE初阶】多线程(4)

欢迎关注个人主页&#xff1a;逸狼 创造不易&#xff0c;可以点点赞吗~ 如有错误&#xff0c;欢迎指出~ 目录 线程安全的 第四个原因 代码举例: 分析原因 解决方法 方法1 方法2 wait(等待)和notify(通知) wait和sleep区别 线程安全的 第四个原因 内存可见性,引起的线程安全问…

CloudXR 套件扩展 XR 工作流

NVIDIA为开发者提供了一个先进的平台&#xff0c;开发者可以在该平台上使用全新NVIDIA CloudXR 套件来创建可扩展、品牌化的定制扩展现实&#xff08;XR&#xff09;产品。 NVIDIA CloudXR 套件基于全新架构而打造&#xff0c;是扩展XR生态的重要工具。它为开发者、专业人士和…

彻底理解浅拷贝和深拷贝

目录 浅拷贝实现 深拷贝实现自己手写 浅拷贝 浅拷贝是指创建一个新对象&#xff0c;这个对象具有原对象属性的精确副本 基本数据类型&#xff08;如字符串、数字等&#xff09;&#xff0c;在浅拷贝过程中它们是通过值传递的&#xff0c;而不是引用传递&#xff0c;修改值并不…

Git项目管理工具

分布式版本控制系统

数据集 wider person 户外密集行人检测 >> DataBall

数据集 wider person 用于野外密集行人检测的多样化数据集 行人检测 目标检测 户外密集行人检测的多样化数据集 WiderPerson: A Diverse Dataset for Dense Pedestrian Detection in the Wild article{zhang2019widerperson, Author {Zhang, Shifeng and Xie, Yiliang and Wa…