QT对象树机制

news2024/12/28 5:08:19

    Qt提供了对象树机制,能够自动、有效的组织和管理继承自QObject的Qt对象。

    每个继承自QObject类的对象通过它的对象链表(QObjectList)来管理子类对象,当用户创建一个子对象时,其对象链表相应更新子类对象信息,对象链表可通过children()获取。

    当父对象析构的时候,其对象链表中的所有(子)对象也会被析构,父对象会自动将其从父对象列表中删除。Qt 保证没有对象会被 delete 两次。开发中手动回收资源时建议使用deleteLater代替delete,因deleteLater多次是安全的,而delete多次是不安全的。

示例

    新建QWidget项目。添加四个类,分别继承QLable、QPushButton、QRadioButton、QGridLayout

class MyLabel : public QLabel;
class MyLayout : public QGridLayout;
class MyPushButton : public QPushButton;
class MyRadioButton : public QRadioButton;

每个子类声明构造和析构函数,函数实现中仅使用qDebug( )输出标识句

//MyLabel类
MyLabel::MyLabel(QWidget *parent):QLabel(parent)
{
    qDebug()<<"MyLabel构造"<<this;
}

MyLabel::~MyLabel()
{
    qDebug()<<"MyLabel析构"<<this;
}
//MyLayout类
MyLayout::MyLayout(QWidget *parent):QGridLayout(parent)
{
    qDebug()<<"MyLayout构造"<<this;
}
MyLayout::~MyLayout()
{
    qDebug()<<"MyLayout析构"<<this;
}
//MyPushButton类
MyPushButton::MyPushButton(QWidget *parent):QPushButton(parent)
{
    qDebug()<<"MyPushButton构造"<<this;
}
MyPushButton::~MyPushButton()
{
    qDebug()<<"MyPushButton析构"<<this;
}
//MyRadioButton类
MyRadioButton::MyRadioButton(QWidget *parent):QRadioButton(parent)
{
    qDebug()<<"MyRadioButton构造"<<this;
}
MyRadioButton::~MyRadioButton()
{
    qDebug()<<"MyRadioButton析构"<<this;
}

    在main函数中,初始化控件和布局管理器,将当前窗体设为控件和布局管理器的父窗体;将控件添加到布局管理器中

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;

    //当前窗体设为父窗体
    MyLabel *myLabel =new MyLabel(&w);
    MyPushButton*myBtn=new MyPushButton(&w);
    MyRadioButton*myRbtn=new MyRadioButton(&w);
    MyLayout*myLayout=new MyLayout(&w);
    //设置文本
    myLabel->setText("子标签");
    myBtn->setText("子按钮");
    myRbtn->setText("子单选");
    //控件添加到布局管理器中
    myLayout->addWidget(myLabel,0,0);
    myLayout->addWidget(myBtn,1,0);
    myLayout->addWidget(myRbtn,2,0);

    return a.exec();

}

 运行结果:

   我们可以看到:在初始化时,当前窗体会先执行构造,随后是其子类执行构造;当窗体关闭时,当前窗体会先执行析构,随后是其子类执行析构,也就是说程序会自动、有效的组织和管理继承自QObject的Qt对象。 只要父类是QObject下的派生类,当父类被销毁或者创建时,其子类也会跟着创建和销毁。

    我们可以使用.children( )函数查看一个类的派生类。这里我们查看当前窗体的派生类。

const QObjectList listW=w.children();
qDebug()<<"w.children()";
foreach (QObject* obj, listW) {
    qDebug()<<obj;
}

运行结果:

    从运行结果我们可以看到: 当我们对控件和布局管理器初始化时,已经将当前窗体设为其父窗体。这些控件和布局管理器也就顺应成章成为当前窗体的子类。

 我们继续对标签控件派生子类

//创建一个sun布局管理器,将标签控件设为其父窗体
MyLayout*sunLayout=new MyLayout(myLabel);
//创建三个按钮控件,这里并未指明其父窗体
MyPushButton*sunBtn1=new MyPushButton;
MyPushButton*sunBtn2=new MyPushButton;
MyPushButton*sunBtn3=new MyPushButton;
//设置文本
sunBtn1->setText("孙按钮1");
sunBtn2->setText("孙按钮2");
sunBtn3->setText("孙按钮3");
//将按钮添加到布局管理器中
sunLayout->addWidget(sunBtn1);
sunLayout->addWidget(sunBtn2);
sunLayout->addWidget(sunBtn3);
//按钮初始时未设定父类,只是将其放入sun布局管理器中。
//sun布局管理器的父窗体设定为myLabel,当myLabel指定其布局管理器为孙布局管理器时,按钮会重新将myLabel设定为其父窗体
myLabel->setLayout(sunLayout);

继续使用.children( )查看标签类的派生类

//查看w子类
const QObjectList listW=w.children();
qDebug()<<"w.children()";
foreach (QObject* obj, listW) {
    qDebug()<<obj;
}

//查看myLabel子类
const QObjectList listLabel=myLabel->children();
qDebug()<<"myLabel.children()";
foreach (QObject* obj, listLabel) {
    qDebug()<<obj;
}

执行结果: 

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

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

相关文章

Docker快速入门

容器Docker技术的演进 1.曾经部署应用&#xff0c;使用物理机部署&#xff0c;这可能会因为不同应用所依赖的版本号不同&#xff0c;不得已购买一套全新的机器&#xff0c;所以成本高、部署慢、资源浪费、难以迁移和拓展、可能会被限定硬件厂商。 2.之后引入了VMVare&#xff…

使用JPA和Hibernate查询分页

介绍 受到我最近给出的StackOverflow答案的启发&#xff0c;我决定是时候写一篇关于使用JPA和Hibernate时查询分页的文章了。 在本文中&#xff0c;您将了解如何使用查询分页来限制 JDBC大小并避免获取不必要的数据。ResultSet 如何在#Hibernate中使用查询分页来限制 JDBC 结…

pytorch深度学习实战lesson32

第三十二课 分布式训练 这个是15年的时候沐神在 CMU 装的一个小机群&#xff0c;里面有30台机器&#xff0c;各机群有大概60块 GPU &#xff0c; 60块 GPU一共花了三四万美金的样子&#xff0c;就是大概20万人民币。沐神表示最亏的是当年他们跑了太多深度学习的实验&#xff0c…

C语言-const char*,char const*,char *const理解

By: Ailson Jack Date: 2022.12.04 个人博客&#xff1a;http://www.only2fire.com/ 本文在我博客的地址是&#xff1a;http://www.only2fire.com/archives/150.html&#xff0c;排版更好&#xff0c;便于学习&#xff0c;也可以去我博客逛逛&#xff0c;兴许有你想要的内容呢。…

传奇外网开服教程-GEE传奇外网全套架设教程

版本不同&#xff0c;所用的引擎和配置也会不同&#xff0c;但是架设方法都是大同小异&#xff0c;今天明杰给大家分享GEE引擎的外网架设教程。​ 需要准备的东西&#xff1a;DBC200版本&#xff0c;补丁&#xff0c;客户端&#xff0c;服务器&#xff0c;备案域名&#xff0c…

【Typora】Typora 新手入门参数配置记录

目录 写在前面 更改图片大小 更换高亮背景 更换主题 写在前面 最近发现一款记笔记的软件——Typora&#xff0c;极简清爽的外观一下子就把我给吸引住了&#xff0c;它支持Markdown 的格式记录&#xff0c;可以让笔记更加有条理、美观&#xff0c;至于 typora 的一些写作语法…

Android入门第43天-Activity与Activity间的互相传值

介绍 今天的课程会比较好玩&#xff0c;我们在之前的Service篇章中看到了一种putExtras和getExtras来进行activity与service间的传值。而恰恰这种传值其实也是Android里的通用传值法。它同样可以适用在activity与activity间传值。 Android中的传值 传单个值 传多个值 具体我…

Spring注解(简便地使用 Bean )

目录 0. 前置工作 1. 将 Bean 存储到容器 2. 对象注入&#xff08;对象装配&#xff09;【从容器中将对象读取出来】 0. 前置工作 创建Maven项目后&#xff0c;在pom.xml中添加Spring所必须的依赖。 <dependencies><dependency><groupId>org.springframe…

22个每个程序员都应该知道的 Git 命令

在这篇文章中&#xff0c;我写了一个快速学习 git 命令的备忘单。它将包括开发人员每天使用的命令&#xff0c;如 git add、git commit、git pull、git fetch&#xff0c;并共享其他有用的 git 命令。 我一直使用Git的一些命令&#xff0c;今天这个列表清单&#xff0c;希望也…

LC-6256. 将节点分成尽可能多的组(二分图判定+BFS)【周赛322】

6256. 将节点分成尽可能多的组 难度困难8 给你一个正整数 n &#xff0c;表示一个 无向 图中的节点数目&#xff0c;节点编号从 1 到 n 。 同时给你一个二维整数数组 edges &#xff0c;其中 edges[i] [ai, bi] 表示节点 ai 和 bi 之间有一条 双向 边。注意给定的图可能是不…

第4章 R语言编程基础——数据整理与预处理

目录 4.1 经济/金融数据库 4.1.1 金融数据与数据库 4.1.2 国外金融数据库概况 4.1.3 国内金融数据库概况 4.1.4 数据的主要内容 4.2 数据格式 4.3 数据的导入 4.3.1 从控制台上输入数据 4.3.2 上市公司财务报表信息读取 4.4 [数据的预处理] 4.1.1 时序数据的预处理 4.1.2…

[附源码]Python计算机毕业设计Django汽车租赁管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

WEB前端网页设计 HTML网页代码 基础参数(二)

html文件调用css文件 <link rel"stylesheet" type"text/css" href"css文件相对路径"/> 设置颜色 Style"color:green;" 设置字体大小 font-size:50px; 设置边框 border&#xff1a;groove&#xff1b; 设置长、宽 heigh…

【通信原理】数字基带传输的线路码型

数字基带传输的线路码型 简单介绍数字基带传输的线路码型的信号波形的特点&#xff0c;以及生成方法。注意观察频谱。文末附Matlab代码。 以下包括双极性NRZ、单极型NRZ、双极型RZ、单极型RZ、差分码&#xff0c;曼切斯特码/数字双相码、密勒码、CMI码、AMI码、HDB3码。 参数…

Spring中Bean的生命周期

先直接说出过程&#xff0c;再来演示具体的操作 过程 简化来说就是 1、首先是实例化Bean&#xff0c;当客户向容器请求一个尚未初始化的bean时&#xff0c;或初始化bean的时候需要注入另一个尚末初始化的依赖时&#xff0c;容器就会调用doCreateBean()方法进行实例化&#xf…

Java多线程之:队列同步器AbstractQueuedSynchronizer原理剖析

Java多线程之&#xff1a;队列同步器AbstractQueuedSynchronizer原理剖析 文章目录Java多线程之&#xff1a;队列同步器AbstractQueuedSynchronizer原理剖析一、AQS的核心思想二、AQS中关键的内部结构一、Node内部类二、CLH队列三、同步状态 state四、Condition条件队列三、AQS…

houdini 之copy to points

将第一个输入中的几何图形复制到第二个输入的点上。 属性备注Source Group几何体来源Target Points要复制到的目标点集合Show Guide Geometry是否显示该操作预览流程Pack and Instance在复制之前将输入几何体打包到嵌入式打包图元中。这导致输入几何被每个副本共享&#xff08;…

跟着实例学Go语言(一)

本教程全面涵盖了Go语言基础的各个方面。一共80个例子&#xff0c;每个例子对应一个语言特性点&#xff0c;非常适合新人快速上手。 教程代码示例来自go by example&#xff0c;文字部分来自本人自己的理解。 本文是教程系列的第一部分&#xff0c;共计20个例子、约1万字。 目…

电子学会2021年3月青少年软件编程(图形化)等级考试试卷(四级)答案解析

目录 一、单选题&#xff08;共15题&#xff0c;每题2分&#xff0c;共30分&#xff09; 二、判断题&#xff08;共10题&#xff0c;每题2分&#xff0c;共20分&#xff09; 三、编程题&#xff08;共4题&#xff0c;共50分&#xff09; 青少年软件编程&#xff08;图形化&a…

python与pycharm配置http服务

下载安装pycharm 下载pycharm 提取码&#xff1a;slgh 在任意自己工作的目录下创建两个文件夹&#xff0c;www文件夹及其目录下cgi-bin文件夹 自己的工作目录\www\cgi-bin 打开pycharm创建工程&#xff0c;选择www\cgi-bin目录 配置cgi&#xff0c;选择Run菜单&#xff0c;…