news 2026/5/4 23:36:59

【Qt】初识(上)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Qt】初识(上)

目录

一、使用qt实现hello world

1.1 图形化方式

1.2 纯代码构建

​编辑

二、对象树

三、乱码问题

四、小结

一、使用qt实现hello world

1.1 图形化方式

双击widget.ui 文件

拖拽控件至ui界面窗口并修改内容;

构建并运行,效果如下所示:

然后我们进入explore到文件管理器里面查看下面这个文件直接拖拽到qt里面。

1.2 纯代码构建

我们先进入widge.cpp文件中。

构建运行就行,只不过是在左上角。

但是我们这里有一个问题,这里我们new了一个对象之后,没有进行delete?这样难道不会出现内存泄漏吗?

关注内存泄漏,是要融入DNA里面的。

内存泄漏是一个非常可怕,非常严重的事情!!

这种问题不容易第一时间发现。

上述代码,在qt中不会产生内存泄漏。

label对象会合适的时候被析构释放~~(虽然没有写,但是确实能释放)

之所以能够把对象释放掉,主要是因为把这个对象挂载到了对象树上面。

二、对象树

Qt中创建很多对象的时候会提供⼀个Parent对象指针,下⾯来解释这个parent到底是⼲什么的。

QObject是以对象树的形怯组织起来的。

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

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

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

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

QWidget是能够在屏幕上显⽰的⼀切组件的⽗类。

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

o当然,我们也可以⾃⼰删除⼦对象,它们会⾃动从其⽗对象列表中删除⽐如,当我们删除了⼀个⼯具栏时,其所在的主窗⼝会⾃动将该⼯具栏从其⼦对象列表中删除,并且⾃动调整屏幕显⽰。

Qt引⼊对象树的概念,在⼀定程度上解决了内存问题。

当⼀个QObject对象在堆上创建的时候,Qt会同时为其创建⼀个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义的。

任何对象树中的QObject对象delete的时候,如果这个对象有parent,则⾃动将其从parentchildren()列表中删除;如果有孩⼦,则⾃动delete每⼀个孩⼦。Qt保证没有QObject会被delete两次,这是由析构顺序决定的。

如果QObject在栈上创建,Qt保持同样的⾏为。正常情况下,这也不会发⽣什么问题。来看下⾯的代码⽚段:

作为⽗组件的window和作为⼦组件的quit都是QObject的⼦类(事实上,它们都是QWidget的⼦类,⽽QWidgetQObject的⼦类)。这段代码是正确的,quit的析构函数不会被调⽤两次,因为标C++要求,局部对象的析构顺序应该按照其创建顺序的相反过程。因此,这段代码在超出作⽤域时,会先调⽤quit的析构函数,将其从⽗对象window的⼦对象列表中删除,然后才会再调⽤window的析构函数。

但是,如果我们使⽤下⾯的代码:

情况⼜有所不同,析构顺序就有了问题。我们看到,在上⾯的代码中,作为⽗对象的window会⾸先被析构,因为它是最后⼀个创建的对象。在析构过程中,它会调⽤⼦对象列表中每⼀个对象的析构函数,也就是说,quit此时就被析构了。然后,代码继续执⾏,在window析构之后,quit也会被析构,因为quit也是⼀个局部变量,在超出作⽤域的时候当然也需要析构。但是,这时候已经是第⼆次调⽤quit的析构函数了,C++不允许调⽤两次析构函数,因此,程序崩溃了。

由此我们看到,Qt的对象树机制虽然在⼀定程度上解决了内存问题,但是也引⼊了⼀些值得注意的事情。这些细节在今后的开发过程中很可能时不时跳出来烦扰⼀下,所以,我们最好从开始就养成良好习惯

💡在 Qt 中,尽量在构造的时候就指定 parent 对象,并且⼤胆在堆上创建。

Qt对象树如图:

对象树大概:

啥也没有。

这里我们新建一个文件,选择cpp,和cpp类。

需要我们手动包头文件。

成功构建了,但是日志有点问题。

三、乱码问题

为什么会出现乱码呢?

字符 编码/解码 - 锤子在线工具

挺好的无广告,纯净。

如何查看编码格式呢?点击explore

日志正常了。

四、小结

1、认识QLebal类,能够在界面上面显示字符串。

通过setText来设置的。参数QString(Qt中把cpp里面很多容器,进行了重新封装,历史原因)。

2、内存泄漏/文件资源泄漏

3、对象树。Qt中通过对象树,来统一的释放界面的控件对象。

Qt还是推荐使用new的方式在堆上创建对象,通过对象树,统一释放对象。

创建对象的时候,在构造函数中,指定父对象(此时才会挂载到对象树中)

4、通过继承自Qt内置的类,就可以达到对现有控件功能进行扩展效果。

Qt内置的QLabel,没法看到销毁的过程。为了看清楚,就创建类mylabel继承Qlabel

重写 析构函数

在析构函数中,加上日志,直观的观察到对象的释放过程了:

也可以在重写控件中的任何功能,不仅仅是析构函数~~达到功能扩张目的~~

5、乱码问题和字符集

6、如何在Qt中打印日志,作为调试信息。

使用cout固然可以,但是并不是上策(字符编码处理的不够好,也不方便统一进行关闭)

Qt中推荐使用qDebug()完成日志的打印。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/4 22:59:27

英雄联盟智能助手Seraphine:三步实现自动BP与战绩分析

英雄联盟智能助手Seraphine:三步实现自动BP与战绩分析 【免费下载链接】Seraphine 英雄联盟战绩查询工具 项目地址: https://gitcode.com/gh_mirrors/se/Seraphine Seraphine是一款基于英雄联盟官方LCU API开发的免费开源工具,专为追求排位赛效率…

作者头像 李华
网站建设 2026/5/4 22:52:38

如何快速构建智能四足机器人:openDogV2完整开发指南

如何快速构建智能四足机器人:openDogV2完整开发指南 【免费下载链接】openDogV2 项目地址: https://gitcode.com/gh_mirrors/op/openDogV2 想要亲手打造一只能够自主行走、感知环境的智能机器狗吗?openDogV2开源项目为你提供了从机械设计到AI集成…

作者头像 李华
网站建设 2026/5/4 22:51:55

Taotoken计费透明化如何让个人开发者清晰掌控预算

Taotoken计费透明化如何让个人开发者清晰掌控预算 1. 计费透明化的核心价值 对于个人开发者和小型团队而言,大模型API的使用成本往往是项目开发中的重要考量因素。Taotoken平台通过精细化的计费设计和直观的数据展示,帮助开发者实现预算的可视化管理。…

作者头像 李华
网站建设 2026/5/4 22:44:33

别再在中断里延时了!FreeRTOS下按键消抖的实战优化(附STM32完整代码)

FreeRTOS下按键消抖的工程实践:从中断陷阱到任务解耦 按键检测是嵌入式系统中最基础却又最容易被轻视的功能模块之一。许多开发者习惯性地在外部中断服务函数(ISR)中直接插入延时消抖代码,这种看似简单的实现方式实则暗藏危机——它可能成为整个系统实时…

作者头像 李华
网站建设 2026/5/4 22:42:08

手术导航倒计时3秒——你的C++渲染引擎还依赖OpenGL固定管线?立即升级至Vulkan 1.3动态渲染通道

更多请点击: https://intelliparadigm.com 第一章:手术导航实时渲染引擎的临床需求与技术演进 现代微创外科对空间感知精度、组织形变响应速度和多模态影像融合能力提出严苛要求。传统离线渲染方案在术中动态追踪器械位姿时,常因延迟超过120…

作者头像 李华