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

news2024/12/26 0:23:26

目录

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可以通过设置开关,实现对于这个发布和调试过程中是否有这个日志的控制,是有好处的~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTML贪吃蛇游戏

文章目录 贪吃蛇游戏 运行效果代码 贪吃蛇游戏 贪吃蛇是一款经典的休闲益智游戏。本文将通过HTML5和JavaScript详细解析如何实现一个简易版的贪吃蛇游戏。游戏的主要逻辑包括蛇的移动、碰撞检测、食物生成等功能。以下是游戏的完整代码及注释解析。&#xff08;纯属好玩&#…

文心一言 VS 讯飞星火 VS chatgpt (347)-- 算法导论23.2 6题

六、假定一个图中所有的边权重均匀分布在半开区间[0,1)内。Prim算法和Kruskal算法哪一个可以运行得更快&#xff1f;如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 在比较Prim算法和Kruskal算法在特定条件下的性能时&#xff0c;我们需要考虑几个因素&#xff…

【大模型专栏—进阶篇】智能对话全总结

大模型专栏介绍 &#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;本文为大模型专栏子篇&#xff0c;大模型专栏将持续更新&#xff0c;主要讲解大模型从入门到实战打怪升级。如有兴趣&#xff0c;欢迎您的阅读。 &#x1f4…

C语言 | Leetcode C语言题解之第400题第N位数字

题目&#xff1a; 题解&#xff1a; //解题思路&#xff1a;计算当前已经经过了多少位&#xff0c;当第一次超过n时&#xff0c;开始获取第n位 int findNthDigit(int n){int i, j, tem_1 10, tem_2 1, res; long count 0; /*i和j用于循环&#xff0c;count用…

Spring Boot集成Akka Cluster快速入门Demo

1.什么是Akka Cluster&#xff1f; Akka Cluster将多个JVM连接整合在一起&#xff0c;实现消息地址的透明化和统一化使用管理&#xff0c;集成一体化的消息驱动系统。最终目的是将一个大型程序分割成若干子程序&#xff0c;部署到很多JVM上去实现程序的分布式并行运算&#xf…

【计网】从零开始使用UDP进行socket编程 --- 服务端业务实现

在我们每个人都曾经历过“沮丧”时刻里&#xff0c; 如果我们不能对别人说有益的好话&#xff0c; 那我们最好还是什么也别说。 --- 卡耐基 《人性的弱点》--- 从零开始使用UDP进行socket编程 1 前情提要2 单词翻译2.1 业务需求2.2 设计字典类2.3 服务端与客户端逻辑2.4 运…

SQLite安装(含安装包)

安装包&#xff1a; 通过百度网盘分享的文件&#xff1a;sqlite-dll-win-x64-3460100.zip 链接&#xff1a;https://pan.baidu.com/s/1852coiq51QcNkeaHdu1Oyg 提取码&#xff1a;v2y6 解压 设置环境变量 验证安装成功 SQLite设置完成

ros学习笔记.4 Path Planning Part 2 (避障)

避障是如何工作的什么是局部规划器&#xff1f;什么是局部成本图&#xff1f;路径规划回顾如何使用动态重新配置和其他 Rviz 工具 局部规划器 一旦全局规划器计算出要遵循的路径&#xff0c;该路径就会发送给局部规划器。然后&#xff0c;局部规划器将执行全局规划的每个部分&…

唯徳知识产权管理系统 DownloadFileWordTemplate 文件读取漏洞复现

0x01 产品简介 唯徳知识产权管理系统,由深圳市唯德科创信息有限公司精心打造,旨在为企业及代理机构提供全方位、高效、安全的知识产权管理解决方案。该系统集成了专利、商标、版权等知识产权的全面管理功能,并通过云平台实现远程在线办公,提升工作效率。是一款集知识产权申…

【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 一、取地址运算符重载 1. const修饰成员函数 2. 取地址运算符重载 二、深究构造函数 三、类型转换 四、static修饰成员 1. static修饰成员变…

监控系列之-prometheus部署说明

一、Prometheus介绍 Prometheus是一款开源的监控系统&#xff0c;主要用于收集、存储和查询时间序列数据&#xff0c;以便于对系统进行监控和分析Prometheus的架构由四个主要组件组成&#xff1a; 1、Prometheus Server &#xff1a;Prometheus Server是Prometheus的核心组件&a…

带你0到1之QT编程:十二、视图宝典,点通views的任督二脉

此为QT编程的第十二谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …

text2sql(NL2Sql)综述《The Dawn of Natural Language to SQL: Are We Fully Ready?》

《The Dawn of Natural Language to SQL: Are We Fully Ready?》(github)出自2024年6月的NL2SQL(Natural language to SQL )综述论文。这篇论文尝试回答如下三个问题&#xff1a; 问题1:NL2SQL的现状是什么&#xff1f;(Q1:Where Are we Now?) 论文图1总结了近20年NL2SQL方法…

【移动端】菜单的自动展开与收回

前言 为了满足手机上菜单栏随用户移动&#xff0c;菜单的自动展示与隐藏&#xff0c;特此记录 基本原理 实现逻辑 window.addEventListener(‘scroll’, debouncedScrollHandler) – 监听文档视图滚动事件 document.querySelector(‘.header’) – 选择器匹配元素 创建show和h…

论文速递!Auto-CNN-LSTM!新的锂离子电池(LIB)剩余寿命预测方法

论文标题&#xff1a;A Data-Driven Auto-CNN-LSTM Prediction Model for Lithium-Ion Battery Remaining Useful Life 期刊信息&#xff1a;IEEE TII (中科院1区, JCR Q1, IF11.7) 引用&#xff1a;Ren L, Dong J, Wang X, et al. A data-driven auto-CNN-LSTM prediction m…

JavaScript web API part3

web API DOM 日期对象 > 得到当前系统的时间 new这个操作就是实例化 语法 const date new Date() or const date new Date(2004-11-3 08:00:00) 可以指定时间 > 可应用于通过系统时间和指定时间实现倒计时的操作 //得到当前时间const date new Date()console.lo…

多维时序 | Matlab基于BO-LSSVM贝叶斯优化最小二乘支持向量机数据多变量时间序列预测

多维时序 | Matlab基于BO-LSSVM贝叶斯优化最小二乘支持向量机数据多变量时间序列预测 目录 多维时序 | Matlab基于BO-LSSVM贝叶斯优化最小二乘支持向量机数据多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于BO-LSSVM贝叶斯优化最小二乘支…

Vue介绍、窗体内操作、窗体间操作学习

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程&#xff1a;封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

树莓派5上手

1 安装系统 Raspberry Pi OS 是基于 Debian 的免费操作系统&#xff0c;针对 Raspberry Pi 硬件进行了优化。Raspberry Pi OS 支持超过 35,000 个 Debian 软件包。树莓派 5 可以安装各种系统&#xff0c;但是如果对于系统没有特殊的要求&#xff0c;还是安装 Raspberry Pi OS …

【MySQL】MySQL索引与事务的透析——(超详解)

前言 &#x1f31f;&#x1f31f;本期讲解关于MySQL索引事务&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;【MySQL】MySQL表的增删改查&#xff08;进阶篇&#xff09;——之查询操作&#xff08;超级详解&#xff09;-CSDN博客 &#x1f308;感…