Qt初识_对象树
个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创Qt初识_对象树
收录于专栏【Qt开发】
本专栏旨在分享学习Qt的一点学习笔记,欢迎大家在评论区交流讨论💌
目录
什么是对象树
为什么要引入对象树?
代码示例
什么是对象树
在 Qt 中创建很多对象的时候会提供一个 Parent 对象指针,下面来解释这个 parent 到底是干什么的。
• QObject 是以对象树的形式组织起来的。
当创建一个 QObject 对象时,会看到 QObject 的构造函数接收一个 QObject 指针作为参数,这个参数就是 parent,也就是父对象指针。
这相当于,在创建 QObject 对象时,可以提供一个其父对象,我们创建的这个 QObject 对象会自动添加到其父对象的 children() 列表。
当父对象析构的时候,这个列表中的所有对象也会被析构。(注意,这里的父对象并不是继承意义上的父类!)
这种机制在 GUI 程序设计中相当有用。例如,一个按钮有一个 QShortcut(快捷键)对象作为其子对象。当删除按钮的时候,这个快捷键理应被删除。这是合理的。
• QWidget 是能够在屏幕上显示的一切组件的父类。
QWidget 继承自 QObject,因此也继承了这种对象树关系。一个孩子自动地称为父组件的一个子组件。因此,它会显示在父组件的坐标系统中,被父组件的边界裁剪。例如,当用户关闭一个对话框的时候,应用程序将其删除,那么我们希望属于这个对话框的按钮、图标等应该一起被删除。事实就是如此,因为这些都是对话框的子组件。
当然,我们也可以自己删除子对象,它们会自动从其父对象列表中删除。比如,当我们删除了一个工具栏时,其所在的主窗口会自动将该工具栏从其子对象列表中删除,并且自动调整屏幕显示。
为什么要引入对象树?
Qt 引入对象树的概念,在一定程度上解决了内存问题。
当一个 QObject 对象在堆上创建的时候,Qt 会同时为其创建一个对象树。不过,对象树中对象的顺序是没有定义的。这意味着,销毁这些对象的顺序也是未定义。
任何对象树中的 QObject 对象 delete 的时候,如果这个对象有 parent,则自动将其从 parent 的 children() 列表中删除;如果有孩子,则自动 delete 每一个孩子。Qt 保证没有 QObject 会被 delete 两次,这是由析构顺序决定的。
如果 QObject 在栈上创建,Qt 保持同样的行为。正常情况下,这也不会发生什么问题。比如下面的代码片段:
作为父组件的 window 和作为子组件的 quit 都是 QObject 的子类(事实上,它们都是 QWidget 的子类,而 QWidget 是 QObject 的子类)。这段代码是正确的,quit 的析构函数不会被调用两次,因为标准 C++ 要求,局部对象的析构顺序应该按照其创建顺序的相反过程。因此,这段代码在超出作用域时,会调用 quit 的析构函数,将其从父对象 window 的子对象列表中删除,然后才会调用 window 的析构函数。
但是,如果我们使用下面的代码:
情况又有所不同,析构顺序就有了问题。我们看到,在上面的代码中,作为父对象的 window 会首先被析构,因为它是最后一个被创建的对象。在析构过程中,它会调用子对象列表中每一个对象的析构函数,也就是说,quit 此时就被析构了。然后,代码继续执行,在 window 析构之后,quit 也会被析构,因为 quit 也是一个局部变量,在超出作用域的时候当然也需要析构。但是,这时候已经是第二次调用 quit 的析构函数了,C++ 不允许调用两次析构函数,因此,程序崩溃了。
由此我们看到,Qt 的对象树机制虽然在一定程度上解决了内存问题,但是也引入了一些值得注意的事情。这些细节在今后的开发过程中很有可能时不时跳出来烦扰一下,所以,我们最好从开始养成好习惯。
在 Qt 中,尽量在构造的时候就指定 parent 对象,并且大胆在堆上创建。
Qt对象树如图:
代码示例
1、创建一个新工程并编译运行,生成如下窗口;(如果还不会的同学,可以参考这篇博客,超级详细:使用Qt Creator创建项目-CSDN博客)

2、选中工程名,鼠标右键 ---> “add new” (或 “添加新文件”)

3、选择 “choose“ ,弹出如下界面;

4、点击 ”下一步“,弹出如下对话框;

5、点击 ”完成“ 之后,手动创建类的头文件以及源文件会自动添加到目标工程中;

6、修改头文件

7,编写源文件

8、编译并运行
9、当关闭弹出的对话框时,就会自动调用按钮的析构函数
(这里不知道怎么回事 Debug没有打印出来, 用了之前的图)
10、执行结果分析:
对象树确保的是先释放子节点的内存,后释放父节点的内存。
而析构函数的调用顺序则不一定遵循上述要求,因此看到子节点的析构执行顺序反而在父节点析构顺序之后。
注意:调用析构函数和释放内存并非是同一件事情。
相关文章:
Qt初识_对象树
个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Qt初识_对象树 收录于专栏【Qt开发】 本专栏旨在分享学习Qt的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 什么是对象树 为什么要引…...
axios的get和post请求,关于携带参数相关的讲解一下
在使用 Axios 发送 HTTP 请求时,GET 和 POST 请求携带参数的方式有所不同。以下是关于这两种请求方法携带参数的详细讲解: GET 请求携带参数 对于 GET 请求,参数通常附加在 URL 之后,以查询字符串的形式传递。 直接在 URL 中拼接…...
Vue前端开发-路由其他配置
在路由文件中,除了跳转配置外,还可以进行路径重定向配置,如果没有找到对应的地址,还可以实现404的配置,同时,如果某个页面需要权限登录,还可以进行路由守卫配置,接下来,分…...
框架建设实战7——定时任务组件
在金融系统中,或者其他对账系统里,往往离不开分布式定时任务。用来做查证或者重试处理。 分布式job目前一般有如下三种: 1.elastic job 当当出品,比较老牌。新公司用的应该不多了。 2.xxl-job 个人开源项目。便于二开;有简洁的后管配置界面,方便接入。 3.powerjob …...
mybatis 整合 ehcache
pom.xml <!-- ehcache依赖 --><dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.1.0</version></dependency>ehcache.xml <?xml version"1.0" en…...
【PlantUML系列】用例图(三)
目录 一、组成部分 二、典型案例 一、组成部分 参与者(Actors):使用关键字 actor 后跟参与者的名称。用例(Use Cases):使用关键字 usecase 后跟用例的名称和编号(可选)。系统边界…...
发送请求时遇到了数据库完整性约束错误 1048 Column ‘platform‘ cannot be null
可以这样解决 在 Vue 2 中封装接口请求时,确保每次请求都包含 platform Header 参数的最佳实践是通过创建一个全局的 Axios 实例,并为这个实例设置默认的 Header。这样可以确保所有通过该实例发送的请求都会自动包含 platform 参数。此外,你…...
三菱FX3U模拟量产品的介绍
FX3u可编程控制器模拟量产品包括:特殊适配器、特殊功能模块的连接 1、连接在FX3U可编程控制器的左侧。 2、连接特殊适配器时,需要功能扩展板。 3、最多可以连接4台模拟量特殊适配器。 4、使用高速输入输出特殊适配器时,请将模拟量特殊适配器连…...
pdf转图片
目录 pdf2image库 PyMuPDF库 python-office库 pdfplumber库 pdf2image库 安装:pip install pdf2image 使用时会报错:pdf2image.exceptions.PDFInfoNotInstalledError: Unable to get page count. Is poppler installed and in PATH? 需要安装 po…...
Go 协程上下文切换的代价
在 Go 语言中,协程(Goroutine)是一种非常轻量级的并发执行单元,设计之初就是为了简化并发编程并提高性能。协程的上下文切换被认为是非常高效的,但是它的真正性能优势需要我们深入了解其背后的机制。 本文将深入探讨 …...
HTTP 持久连接(长连接)
HTTP 持久连接(长连接) HTTP 持久连接(HTTP Persistent Connections),也常被称作 HTTP 长连接,是 HTTP 协议中的一种重要特性,以下是关于它的详细介绍: 一、基本概念 在传统的 HTT…...
12月10日IO
作业:使用read和write实现拷贝文件,将1.txt内容前一半拷贝给2.txt后一半拷贝给3.txt #include <myhead.h>int main(int argc, const char *argv[]) {//打开三个文件int fd1,fd2,fd3;fd1open("1.txt",O_RDONLY);fd2open("2.txt&quo…...
Composite Pattern
Composite Pattern The intent of Composite pattern is to composite objects into tree structures to represent a “part-whole” hierarchy .The Composite Pattern allow clients to treat individual objects and composite objects uniformly. UML Used in Qt Exam…...
Springboot MVC
1. Springboot为MVC提供的自动配置 Spring Boot 为 Spring MVC 提供了自动配置,这在大多数应用程序中都能很好地工作。除了已经实现了 Spring MVC 的默认功能外,自动配置还提供了以下特性: 包括 ContentNegotiatingViewResolver 和 BeanNam…...
MySQL数据表记录增操作
对数据库的操作用的最最频繁的呢,总结起来就四个字:增删改查! 查是属于DQL(Data QueryLanguage ,数据查询语言)部分,而增、改、删属于DML(Data Manipulation Language, 数据操纵语言) 增:作用是往数据库的数据表里写入记录值 语…...
maven报错“找不到符号“
问题 springboot项目 maven编译打包过程,报错"找不到符号" 解决 很多网上方法都试过,都没用 换jdk,把17->21...
python进阶-05-利用Selenium来实现动态爬虫
python进阶-05-利用Selenium来实现动态爬虫 一.说明 这是python进阶部分05,我们上一篇文章学习了Scrapy来爬取网站,但是很多网站需要登录才能爬取有用的信息,或者网站的静态部分是一个空壳,内容是js动态加载的,或者人机验证&…...
P1226 【模板】快速幂
题目描述 给你三个整数 𝑎,𝑏,𝑝求 𝑎𝑏 mod 𝑝 输入格式 输入只有一行三个整数,分别代表 𝑎,𝑏,𝑝 输出格式 输出一行一个字符串 a^b mod ps…...
【C++】求第二大的数详细解析
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述💯输入描述💯解题思路分析1. 题目核心要求2. 代码实现与解析3. 核心逻辑逐步解析定义并初始化变量遍历并处理输入数据更新最大值与次大值输…...
从零开始学TiDB(3)TiKV 持久化机制
如图,每个TiKV有两个rocksdb实例,rocksdbKV复制存储键值对,rocksdb raft负责存储复制的日志 。 每个region及其副本构成了raft group。这个OB的Zone其实有点类似,在OB中每个Unit及其副本构成了paxos组,在TiDB中叫raft…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
Linux离线(zip方式)安装docker
目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1:修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本:CentOS 7 64位 内核版本:3.10.0 相关命令: uname -rcat /etc/os-rele…...
