【Qt开发流程】之对象模型3:对象树及其所有权

news2025/1/21 6:34:45

描述

Qt对象树是一种基于父子关系的对象管理机制,用于管理Qt应用程序中的所有对象。在Qt中,每个对象都可以拥有一个或多个子对象,并且每个子对象只能属于一个父对象。每个对象的所有权(也称为生存期)由其父对象控制。当父对象销毁时,它们会自动销毁其所有子对象,以确保在程序结束之前释放所有内存。
对象在对象树中组织自己。当you使用另一个对象作为父对象创建QObject时,它被添加到父对象的children()列表中,并在父对象被删除时被删除。事实证明,这种方法非常适合GUI对象的需要。例如,QShortcut(键盘快捷键)是相关窗口的子窗口,因此当用户关闭该窗口时,快捷键也会被删除。
QWidgetQt Widgets模块的基本类,它扩展了父子关系。子部件通常也成为子部件,即它显示在其父部件的坐标系统中,并被其父部件的边界以图形方式剪切。例如,当应用程序在关闭消息框后删除消息框时,消息框的按钮和标签也会被删除,正如我们所希望的那样,因为按钮和标签是消息框的子框。
程序员也可以自己删除子对象,将自己从父对象中移除。例如,当用户删除工具栏时,可能导致应用程序删除其QToolBar对象之一,在这种情况下,工具栏的QMainWindow父组件将检测到更改并相应地重新配置其屏幕空间。
调试函数QObject:: dumpobjectreree()QObject::dumpObjectInfo()在应用程序看起来或行为异常时通常很有用。
QObject:: dumpobjectreree():

this->dumpObjectTree();

在这里插入图片描述
QObject::dumpObjectInfo():

checkBox->dumpObjectInfo();

在这里插入图片描述

实际应用

在实际应用中,可以通过以下几种方式创建对象树:

  1. 通过new运算符手动分配内存来创建对象,然后使用QObject的setParent()函数将它们移动到树中。

  2. 使用Qt的自动内存管理机制,例如Qt的容器类,这些类在使用时会自动管理对象的内存,使它们成为树中的子对象。

对象的构造和销毁顺序

当在堆上创建QObjects(即用new创建)时,可以以任何顺序从它们构造一个树,然后,树中的对象可以以任何顺序销毁。当树中的任何QObject被删除时,如果该对象有父对象,析构函数将自动从其父对象中删除该对象。如果对象有子对象,析构函数会自动删除每个子对象。无论销毁顺序如何,QObject都不会被删除两次。

当在堆栈上创建QObjects时,同样的行为也适用。通常情况下,破坏的顺序不会造成问题。如下面的代码片段:

  int main()
  {
      QWidget window;
      QPushButton quit("Quit", &window);
      ...
  }

父窗口和子窗口都是QObject,因为QPushButton继承了QWidget,而QWidget继承了QObject。这段代码是正确的:quit的析构函数不会被调用两次,因为c++语言标准(ISO/IEC 14882:2003)指定局部对象的析构函数以与其构造函数相反的顺序调用。因此,首先调用子进程的析构函数quit,并在调用window的析构函数之前将自己从父进程window中移除。

但是现在考虑一下如果我们交换构造顺序会发生什么,如下面代码所示:

    QPushButton quit("Quit");
    QWidget window;

    quit.setParent(&window);

在这种情况下,破坏的顺序会引起问题。父类的析构函数首先被调用,因为它是最后创建的。然后调用它的子孩子quit的析构函数,这是不正确的,因为quit是一个局部变量。当quit随后超出作用域时,它的析构函数将被再次调用,这次是正确的,但是损害已经造成了。

示例

#include <QtWidgets>

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    
    QWidget *mainWidget = new QWidget; // 创建主窗口 Widget
    QVBoxLayout *layout = new QVBoxLayout(mainWidget); // 创建主窗口的布局管理器
        
    QLabel *label = new QLabel("Hello Qt!"); // 创建标签对象
    layout->addWidget(label); // 将标签对象添加到布局管理器中

    QPushButton *button = new QPushButton("Click me!"); // 创建按钮对象
    layout->addWidget(button); // 将按钮对象添加到布局管理器中

    mainWidget->show(); // 显示主窗口
    
    return app.exec(); // 进入 Qt 事件循环
}

如果希望将标签和按钮对象添加到主窗口的对象树中,可以使用QWidget的setParent()函数将它们添加为主窗口的子对象:

label->setParent(mainWidget);
button->setParent(mainWidget);

这样,当主窗口对象被销毁时,它们也会被自动销毁。

结论

努力不一定有收获,但是不努力一定会很舒服哦

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

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

相关文章

LangChain学习一:模型-实战

文章目录 上一节内容学习目标&#xff1a;模型&#xff08;models&#xff09;学习内容一&#xff1a;模型分类学习内容二&#xff1a;不同模型实战3.1 Chat-聊天模型3.1.1 声明3.1.2 Chat-聊天类型实战3.1.2.1 AIMessage&#xff08;AI 消息&#xff09;3.1.2.2 HumanMessage&…

力扣46. 全排列(java 回溯法)

Problem: 46. 全排列 文章目录 题目描述思路解题方法复杂度Code 题目描述 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 思路 1.该题目要求求出一个数组的全排列&#xff0c;我们可以利用回溯模拟出一个对数组中所有…

9_企业架构队列缓存中间件分布式Redis

企业架构队列缓存中间件分布式Redis 学习目标和内容 1、能够描述Redis作用及其业务适用场景 2、能够安装配置启动Redis 3、能够使用命令行客户端简单操作Redis 4、能够实现操作基本数据类型 5、能够理解描述Redis数据持久化机制 6、能够操作安装php的Redis扩展 7、能够操作实现…

maven生命周期回顾

目录 文章目录 **目录**两种最常用打包方法&#xff1a;生命周期&#xff1a; 两种最常用打包方法&#xff1a; 1.先 clean&#xff0c;然后 package2.先 clean&#xff0c;然后install 生命周期&#xff1a; 根据maven生命周期&#xff0c;当你执行mvn install时&#xff0c…

JAVA IO:NIO

1.阻塞 IO 模型 ​ 最传统的一种 IO 模型&#xff0c;即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后&#xff0c;内核会去查看数据是否就绪&#xff0c;如果没有就绪就会等待数据就绪&#xff0c;而用户线程就会处于阻塞状态&#xff0c;用户线程交出 CPU。当…

Unity 简单打包脚本

打包脚本 这个打包脚本适用于做demo&#xff0c;脚本放在Editor目录下 using System; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEngine;public class BuildAB {[MenuItem("Tools/递归遍历文件夹下…

构建第一个事件驱动型 Serverless 应用

我相信&#xff0c;我们从不缺精彩的应用创意&#xff0c;我们缺少的把这些想法变成现实的时间和付出。 我认为&#xff0c;无服务器技术真的有助于最大限度节省应用开发和部署的时间&#xff0c;并且无服务器技术用可控的成本&#xff0c;实现了我的那些有趣的想法。 在我 2…

kali学习

目录 黑客法则&#xff1a; 一&#xff1a;页面使用基础 二&#xff1a;msf和Windows永恒之蓝漏洞 kali最强渗透工具——metasploit 介绍 使用永恒之蓝进行攻击 ​编辑 使用kali渗透工具生成远程控制木马 渗透测试——信息收集 域名信息收集 黑客法则&#xff1a; 一&…

Java架构师系统架构设计原则应用

目录 1 导语2 如何设计高并发系统:局部并发原则3 如何设计高并发系统:服务化与拆分4 高可用系统有哪些设计原则?5 如何保持简单轻量的架构-DRY、KISS,YAGNI原则6 如何设计组件间的交互和行为-HCLC,CQS,SOC7 框架层面的发展趋势-约定大于配置想学习架构师构建流程请跳转:…

有源滤波器在矿区配电网中的应用

针对目前有源滤波器应用于矿区谐波治理时电网频率适应能力较低的问题&#xff0c;针对定采样点数字控制系统提出了一种具有频率自适应能力的谐振控制策略。该策略不仅可以实现对电网频率波动的自适应&#xff0c;提高滤波器补偿效果&#xff0c;而且不需要在线对控制器参数进行…

ansible常用模块介绍

ansible运行模块的两种方式 Ad - Hoc 利用 ansible 命令直接完成管理 &#xff0c; 主要用于临时命令使用场景 ansible westos -m shell -a ls /mnt playbook ansible 脚本 &#xff0c; 主要用于大型项目场景 &#xff0c; 需要前期的规划 vim test.yml - hosts: all task…

【Docker】从零开始:13.Docker安装tomcat

Docker】从零开始&#xff1a;13.Docker安装Tomcat 下载Tomcat镜像启动Tomcat镜像新版本Tomcat修改访问Tomact首页 下载Tomcat镜像 [rootdocker ~]# docker pull tomcat Using default tag: latest latest: Pulling from library/tomcat 0e29546d541c: Pull complete 9b829c7…

IDEA加载阿里Java规范插件

IDEA加载阿里巴巴Java开发手册插件&#xff0c;在写代码的时候会自动扫描代码规范。 1、打开Settings 2、打开Plugins 3、搜索Alibaba Java Code Guidelines&#xff08;XenoAmess TPM&#xff09;插件&#xff0c;点击Install进行安装&#xff0c;然后重启IDE生效。 4、鼠标右…

Zabbix 5.0 安装部署

一、系统准备工作&#xff1a; Linux &#xff1a; centos 7 mini zabbix-server版本 5.0 LTS 二、安装配置步骤 系统更新 yum update -y 关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 0 #临时 sed -i s/SELINUXenforcing/SELINU…

User: zhangflink is not allowed to impersonate zhangflink

使用hive2连接进行添加数据是报错&#xff1a; [08S01][1] Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask. User: zhangflink is not allowed to impersonate zhangflink 有些文章说需要修…

烟感监控:这个技巧是真的香,后悔没早点知道!

在现代社会&#xff0c;安全意识的提升成为各行各业关注的焦点之一。特别是在建筑、工业和住宅领域&#xff0c;火灾作为一种突发性、破坏性极强的灾害&#xff0c;给人们的生命和财产安全带来了巨大的威胁。 因此&#xff0c;为了有效预防和应对火灾&#xff0c;烟感监控系统逐…

【Angular开发】Angular中的高级组件

在这个博客中&#xff0c;我将解释Angular中的几个高级组件和机制&#xff0c;它们增强了灵活性、可重用性和性能。 通过熟悉这些高级组件和机制&#xff0c;您可以提高您的Angular开发技能&#xff0c;并在应用程序中利用灵活性、可重用性和性能优化的能力。让我们开始吧&…

iOS ------ 调用高德地图SDK

一&#xff0c;导入第三方库 这里使用CocoaPods安装SDK&#xff0c;方法和前面导入第三方库相同 1.打开终端&#xff0c;cd 文件路径 进入到所创建的项目文件中 2.输入pod init为该项目创建Podfile文件 3.编辑 Podfile 文件 Podfile文件内容如下&#xff1a; platform :ios,…

yolov1网络结构

YOLO神经网络结构如下图所示。把一幅480x480的原图分割成7x749个网格&#xff0c;每个网格要预测两个预选框&#xff08;bounding box&#xff09;的坐标&#xff08;x&#xff0c;y&#xff0c;w&#xff0c;h&#xff09;&#xff0c;其中x和y表示box中心点与该格子边界的相对…

Netty中Channel的isWritable方法理解

目录 初见 深入 需要注意 对待超SIZE情况开源项目怎么做 1、seata中 2、SUMMER中 3、一些资料中 总结 初见 以下是包中注释 Returns true if and only if the I/O thread will perform the requested write operation immediately. Any write requests made when t…