初识Qt:从Hello world到对象树的深度解析

Qt中的对象树深度解析

  • Hello world
    • 1.图形化界面创建
    • 命令行式创建
      • 在栈上创建
      • 在堆上创建
        • 为什么传文本需要QString,std::string不行吗?
        • 那为什么要传入this指针?为什么new后不用显示调用delete函数呢,不会造成内存泄漏问题吗?
  • 一、对象树的基本概念
  • 二、对象树的创建
    • 验证对象树的内存管理
  • 三、对象树的用途
  • 四、对象树的注意事项

Hello world

1.图形化界面创建

在这里插入图片描述
在这里插入图片描述
与上述图片中的树形结构对应,则XML代码为在这里插入图片描述

命令行式创建

在栈上创建

    //构建QLabel标签
    QLabel label1;
    label1.setText(QString("Hello World"));

这里我们采用在栈上创建Label对象,并设置其文本为Hello world,但是为什么在对话框没有显示呢?
在这里插入图片描述

局部变量:label1是一个局部变量,它在构造函数结束时会被销毁。即使您将其添加到了布局中,由于它在构造函数结束后不再存在,所以标签也不会显示出来。

在堆上创建

    //构建QLabel标签
    QLabel* label1=new QLabel(this);
    label1->setText(QString("Hello World"));

在这里插入图片描述
在这里插入图片描述

通过上述我们发现,现在可以显示在对话框了,但是也存在上述几个问题——

为什么传文本需要QString,std::string不行吗?

在Qt中,QString是Qt框架提供的字符串类,它与C++标准库中的std::string有所不同。尽管在某些情况下,你可以使用std::string,但在Qt应用程序中,通常建议使用QString,因为它具有以下优势:

  1. 跨平台性:QString是Qt框架的一部分,而且是跨平台的。这意味着你可以在不同的操作系统上(如Windows、Linux、macOS等)使用相同的代码,并且QString的行为将是一致的。相比之下,std::string是C++标准库的一部分,可能在不同的编译器或操作系统上有不同的实现和行为。

  2. Unicode支持:QString天生支持Unicode字符集,这意味着它可以轻松处理各种语言和特殊字符,而不会出现乱码或截断等问题。与之相比,std::string在处理Unicode字符时可能会面临一些挑战,需要谨慎处理。

  3. 方便的API:QString提供了丰富的API,可以方便地进行字符串操作,如拼接、查找、替换、大小写转换等。此外,QString还支持使用arg()方法进行字符串格式化,使得字符串处理更加灵活和便捷。

  4. 与Qt框架的集成:QString与Qt框架的其他部分无缝集成,如信号槽机制、国际化支持等。使用QString可以更容易地与其他Qt类进行交互,并且可以利用Qt提供的丰富功能来进行字符串处理。

所以,尽管string也可以作为参数传入,但是为了防止出现乱码(编码不一致)的问题,还是老实用QString传入较好(不用显示写入,通过构造函数,上述 label1->setText("Hello World");也是可以的)

那为什么要传入this指针?为什么new后不用显示调用delete函数呢,不会造成内存泄漏问题吗?

在Qt中,使用this作为父对象参数来创建对象,是为了将新创建的对象添加到当前对象的子对象列表中,并且在当前对象销毁时,这些子对象也会被自动销毁。在示例代码中,通过new QLabel(this)语句创建了一个QLabel对象,并将当前Widget对象作为其父对象

现在来解释一下为什么要传递this:

  1. 对象树管理:Qt中的对象树是通过父子关系来管理的,每个QObject都可以有一个父对象。当一个对象拥有父对象时,它就成为父对象的子对象,而且其生命周期也受父对象管理。通过将this作为父对象参数传递给new QLabel(),你告诉Qt将新创建的QLabel对象添加到当前Widget对象的子对象列表中。

  2. 内存管理:传递this作为父对象参数可以确保在当前Widget对象被销毁时,其所有子对象也会被自动销毁。这是因为Qt会自动管理父对象与其子对象之间的关系,并在父对象销毁时递归地销毁其所有子对象,从而避免内存泄漏。

因此,通过将this作为父对象参数传递给new QLabel(),可以实现对象之间的正确管理和内存自动释放。

那么肯定会疑惑,Qt真的能安全地将我们构造的对象释放吗?你怎么知道?

引入对象树

在Qt这个强大的跨平台C++图形用户界面应用程序开发框架中,对象树是一个核心概念。它不仅为Qt应用程序的内存管理提供了便利,还确保了Qt对象之间的父子关系清晰、易于理解。本文将深入解析Qt中的对象树机制,帮助读者更好地理解其在Qt应用程序中的作用。

一、对象树的基本概念

Qt中的对象树是一个树形结构,其中每个节点都是一个QObject或其派生类的实例。这些对象通过父子关系连接在一起,形成了一个层次结构。在这个结构中,每个对象都可以有一个父对象(除了根对象外),并且可以有多个子对象。
如下图所示为一颗Qt的n叉树,树的根节点为QObject
在这里插入图片描述

二、对象树的创建

在Qt中,对象的创建通常伴随着父子关系的建立。当一个QObject对象在创建时指定了一个父对象,那么这个新创建的对象就会自动添加到父对象的子对象列表中。同时,父对象会接管其所有子对象的内存管理。这意味着,当父对象被删除时,其所有子对象也会被自动删除,从而避免了内存泄漏的问题。

验证对象树的内存管理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

tips: .h 与 .cpp之间可以通过F4快速切换

在这里插入图片描述
完成创建后编译代码,发现出现了和上述一样的结果
在这里插入图片描述
当我们关闭对话框时,则会发现其默认调用了析构函数

在这里插入图片描述

tips:调⽤析构函数和释放内存并⾮是同⼀件事情.

因此验证了对象树内存管理的机制

三、对象树的用途

  1. 内存管理:如前所述,对象树为Qt应用程序提供了自动的内存管理机制。这种机制通过父子关系来确保当一个对象不再需要时,它的所有子对象也会被正确地删除。
  2. 事件传播:在Qt中,事件(如鼠标点击、键盘输入等)是通过事件系统来传播的。当一个事件发生时,它首先被发送到接收该事件的对象。如果该对象无法处理该事件,那么事件就会沿着对象树向上传播,直到找到一个能够处理该事件的对象为止。这种机制使得Qt能够轻松地处理复杂的事件传递逻辑。
  3. 资源共享:在Qt中,一些资源(如字体、颜色等)可以在对象树中进行共享。当一个对象设置了某个资源时,它的所有子对象都可以访问和使用这个资源。这种机制减少了资源的使用量,提高了应用程序的性能。

四、对象树的注意事项

  1. 避免循环引用:循环引用是指两个或多个对象相互引用,形成一个环路。在构建对象树时,要注意避免循环引用的问题。即一个对象不能成为自己的祖先对象的子对象,否则会导致内存泄漏和其他问题。
// 错误示例:创建循环引用的对象树
QObject *parent = new QObject;
QObject *child = new QObject(parent);
parent->setParent(child); // 这里会导致循环引用

// 正确示例:避免循环引用
QObject *parent = new QObject;
QObject *child = new QObject(parent); // 正确,child 是 parent 的子对象
  1. 谨慎使用setParent()方法:setParent()方法用于在运行时更改对象的父对象。但是,需要谨慎使用,因为它可能会导致一些意想不到的问题,例如事件传播错误或资源共享问题。在使用setParent()方法时,需要确保不会破坏对象之间的逻辑关系或导致不一致的状态。
// 示例:谨慎使用 setParent() 方法
QObject *parent = new QObject;
QObject *child = new QObject;

// 设置 child 的父对象为 parent
child->setParent(parent);

// 如果后续不再需要 parent,要特别小心
delete parent; // 这可能会导致 child 悬空指针,引发错误
  1. 注意对象的生命周期:虽然对象树提供了自动的内存管理机制,但是开发者仍然需要注意对象的生命周期。在不再需要某个对象时,最好显式地删除它(而不是仅仅断开它与父对象的连接),以确保资源的及时释放。可以通过delete操作符来显式删除对象,或者使用QObject的父子关系自动管理机制。
// 示例:注意对象的生命周期
QObject *parent = new QObject;
QObject *child = new QObject(parent);

// 显式删除对象
delete parent; // 这将同时删除 parent 和 child

// 或者使用父子关系自动管理
// 当 parent 被删除时,child 会自动删除

总结

Qt中的对象树是一个强大而灵活的概念,它为Qt应用程序提供了自动的内存管理、事件传播和资源共享等机制。通过深入理解对象树的工作原理和使用方法,开发者可以更加高效、安全地开发Qt应用程序。

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

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

相关文章

国产操作系统上使用SQLynx连接数据库 _ 统信 _ 麒麟 _ 中科方德

原文链接:国产操作系统上使用SQLynx连接数据库 | 统信 | 麒麟 | 中科方德 Hello,大家好啊!今天我们将探讨如何在国产操作系统上使用SQLynx。这是一款功能强大的数据库管理工具,可以帮助用户高效地管理和操作数据库。本文将详细介绍…

2024 电工杯高校数学建模竞赛(A题)数学建模完整思路+完整代码全解全析

你是否在寻找数学建模比赛的突破点?数学建模进阶思路! 作为经验丰富的数学建模团队,我们将为你带来2024电工杯数学建模竞赛(B题)的全面解析。这个解决方案包不仅包括完整的代码实现,还有详尽的建模过程和解…

Docker搭建mysql性能测试环境

OpenEuler使用Docker搭建mysql性能测试环境 一、安装Docker二、docker安装mysql三、测试mysql连接 一、安装Docker 建立源文件vim /etc/yum.repos.d/docker-ce.repo增加内容[docker-ce-stable] nameDocker CE Stable - $basearch baseurlhttps://repo.huaweicloud.com/docker…

NLP(18)--大模型发展(2)

前言 仅记录学习过程,有问题欢迎讨论 Transformer结构: LLM的结构变化: Muti-head 共享: Q继续切割为muti-head,但是K,V少切,比如切为2个,然后复制到n个muti-head减少参数量,加速训练 atte…

STM32-串口通信波特率计算以及寄存器的配置详解

您好,我们一些喜欢嵌入式的朋友一起建立的一个技术交流平台,本着大家一起互相学习的心态而建立,不太成熟,希望志同道合的朋友一起来,抱歉打扰您了QQ群372991598 串口通信基本原理 处理器与外部设备通信的两种方式 并行…

flume使用实例

1、监听端口a1.sources.r1.type netcat 配置文件nc-flume-console.conf # Name the components on this agent a1 表示jvm进程名 a1.sources r1 a1.sinks k1 a1.channels c1 # Describe/configure the source a1.sources.r1.type netcat a1.sources.r1.bind node…

《王者荣耀》4月狂揽2.34亿美元 单日流水1亿美元 全球销量第二

易采游戏网5月24日消息,在刚刚过去的四月,全球手游市场迎来了一场收益的盛宴,其中《王者荣耀》以其惊人的吸金能力,以2.34亿美元的月收入在全球手游排行榜上位列第二。4月5日,这款由腾讯游戏开发的多人在线战斗竞技游戏…

软考考前前怎么复习?

有一些经验,可以和大家分享一下。 软考的考试内容 软考包含许多科目,共分为五大类,27个专业。 软考的等级不同,考试内容也有所不同。初级和中级考试只包括两门科目,而高级则需要考三门科目。每门科目满分75分&#x…

knife4j-swagger

文章目录 knife4j-swagger第 1 步:引入 jar 包第 2 步:添加注释来开启 knife4j第 3 步:验证问题解决新增功能:ApiOperationSupport 注解新增功能:DynamicParameters 注解忽略参数属性 knife4j-swagger knife4j 是 Swa…

W801 实现获取天气情况

看了小安派(AiPi-Eyes 天气站)的源码,感觉用W801也可以实现。 一、部分源码 main.c #include "wm_include.h" #include "Lcd_Driver.h"void UserMain(void) {printf("\n user task \n");Lcd_Init();Lcd_Clea…

Qt官方示例---opengl

文件相对路径:Examples\Qt-5.9.1\opengl 2dpainting cube computegles31 contextinfo hellogl2 hellowindow paintedwindow qopenglwidget qopenglwindow textures threadedqopenglwidget

VirtualBox设置共享文件夹,用于在Window11 和 Ubuntu22 中共享文件,2024亲测可用

VirtualBox设置共享文件夹,用于在Window11 和 Ubuntu22 中共享文件,2024亲测可用 Windows操作 1、新建文件夹,用于共享 Linux操作 1、添加共享文件夹 共享文件夹路径:选择Windows系统中你需要共享的文件夹 共享文件夹名称&am…

ROS2入门21讲__第07讲__节点:机器人的工作细胞

目录 前言 通信模型 案例一:Hello World节点(面向过程) 运行效果 代码解析 创建节点流程 案例二:Hello World节点(面向对象) 运行效果 代码解析 创建节点流程 案例三:物体识别节点 …

小蓝和小青在做数字破解游戏

小蓝和小青在做数字破解游戏,设某图案由m*n的0和1点阵组成,依照以下规则破解连续一组数值,从点阵图第一行第一个符号开始计算,从左到右,由上至下。第一个数表示连续有几个0,第二个数表示接下来连续有几个1,…

Nuxt3 实战 (七):配置 Supabase 数据库

前言 这个章节我们要先把数据库的环境配置好,古人云:工欲善其事,必先利其器。 这两天我一直在网上寻找最适合 Nuxt 的数据库,之前在做个人项目时经常用的是 Mysql 和 MongoDB,也用过 ORM 框架比如:Sequel…

flutter webview加载本地文件出现跨域解决方案

一直报错 [INFO:CONSOLE(17)] "Access to image at file:///android_asset/flutter_assets/assets/jump/box_bottom.png from origin null has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome…

留学服务平台应用架构的设计与优化

随着全球化进程的加速和人们对国际化教育的需求不断增长,留学服务平台在满足学生留学需求的同时也面临着诸多挑战。在这样的背景下,设计一个高效、稳定且安全可靠的留学服务平台应用架构显得尤为重要。本文将就留学服务平台应用架构的设计与优化进行探讨…

JKTECH柔性振动盘用途

柔性振动盘的作用与用途 在现代工业自动化领域,柔性振动盘凭借其独特的功能和广泛的应用场景,正逐渐成为生产线上的重要工具。柔性振动盘,又称柔性供料器,它结合了传统振动盘的高效性和现代自动化技术的灵活性,为各种…

vulhub——Aria2、bash、catic

文章目录 一、Aria2 任意文件写入漏洞二、CVE-2014-6271(Bash Shell 漏洞)三、CVE-2022-46169(Cacti 前台命令注入漏洞) 一、Aria2 任意文件写入漏洞 Aria2是一个命令行下轻量级、多协议、多来源的下载工具(支持 HTTP…

【MySQL精通之路】InnoDB(10)-行格式

目录 1.表数据结构 1.1 聚集索引数据结构 1.2 辅助索引数据结构 2.行格式 2.1 REDUNDANT行格式 2.2 REDUNDANT存储特性 2.3 COMPACT行格式 2.4 COMPACT存储特性 2.5 DYNAMIC行格式 2.6 DYNAMIC存储特性 2.7 COMPRESSED行格式 2.8 COMPRESSED存储特性 3.定义表格的…