当前位置: 首页 > news >正文

Qt 调用setLayout后,父对象自动设置

1、先来看一个简单的Qt程序,代码如下:

LabelEx.h 

#ifndef LABELEX_H
#define LABELEX_H#include <qlabel.h>// 简单重写QLabel类
class LabelEx : public QLabel
{Q_OBJECT
public:explicit LabelEx(QWidget *parent = nullptr);~LabelEx();signals:
};#endif // LABELEX_H

LabelEx.cpp

#include "LabelEx.h"
#include <qdebug.h>LabelEx::LabelEx(QWidget *parent): QLabel{parent}
{}LabelEx::~LabelEx()
{qDebug() << "LabelEx destructor";
}

测试对话框:

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include "LabelEx.h"class Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();private:void init();private:LabelEx *m_lbInfo = nullptr;
};
#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include <qboxlayout.h>
#include <qdebug.h>Dialog::Dialog(QWidget *parent): QDialog(parent)
{init();
}Dialog::~Dialog() {}void Dialog::init()
{setMinimumSize(200, 200);m_lbInfo = new LabelEx();        // 无父对象m_lbInfo->setText("测试1");QHBoxLayout *hLay = new QHBoxLayout();    // 无父对象hLay->addWidget(m_lbInfo);if (m_lbInfo->parent() == hLay) {qDebug() << "m_lbInfo->parent() == hLay";}if (m_lbInfo->parent() == this) {qDebug() << "m_lbInfo->parent() == this";}if (m_lbInfo->parent() == nullptr) {qDebug() << "m_lbInfo->parent() == nullptr";}if (hLay->parent() == this) {qDebug() << "hLay->parent() == this";}if (hLay->parent() == nullptr) {qDebug() << "hLay->parent() == nullptr";}
}

运行后可以看到打印信息:

m_lbInfo->parent() == nullptr
hLay->parent() == nullptr

关闭对话框后,m_lbInfo没有调用析构函数,与hLay都存在内存泄漏的风险(因为没有父对象,不会自动释放资源)

修改Dialog::init()后:

void Dialog::init()
{setMinimumSize(200, 200);m_lbInfo = new LabelEx();        // 无父对象m_lbInfo->setText("测试1");QHBoxLayout *hLay = new QHBoxLayout();        // 无父对象hLay->addWidget(m_lbInfo);this->setLayout(hLay);if (m_lbInfo->parent() == hLay) {qDebug() << "m_lbInfo->parent() == hLay";}if (m_lbInfo->parent() == this) {qDebug() << "m_lbInfo->parent() == this";}if (m_lbInfo->parent() == nullptr) {qDebug() << "m_lbInfo->parent() == nullptr";}if (hLay->parent() == this) {qDebug() << "hLay->parent() == this";}if (hLay->parent() == nullptr) {qDebug() << "hLay->parent() == nullptr";}
}

其实只是增加一行代码:this->setLayout(hLay)

可以看出打印信息:

m_lbInfo->parent() == this
hLay->parent() == this

由此可见,QWidget对象在调用setLayout(QLayout *lay)后,会把lay和lay布局中的QWidget对象都设为自身的子对象。

关闭对话框后,打印信息:LabelEx destructor

m_lbInfo调用了析构函数,自动释放了资源。

【题外话】QObject对象在释放资源时,会自动释放它子对象的资源,相信大家都明白,因为QObject有一个QObjectList类型的对象,专门管理子对象,包括释放自身资源前会遍历释放子对象资源。

2、扩展

修改Dialog类

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include "LabelEx.h"class Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();private:void init();private:QWidget *m_wgt = nullptr;LabelEx *m_lbInfo = nullptr;
};
#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include <qboxlayout.h>
#include <qdebug.h>Dialog::Dialog(QWidget *parent): QDialog(parent)
{init();
}Dialog::~Dialog() {}void Dialog::init()
{setMinimumSize(600, 200);m_wgt = new QWidget();              // 无父对象m_lbInfo = new LabelEx(m_wgt);      // 父对象为m_wgtm_lbInfo->setText("测试1:");QHBoxLayout *hLay = new QHBoxLayout();hLay->addWidget(m_lbInfo);m_wgt->setLayout(hLay);QVBoxLayout *vLay = new QVBoxLayout();vLay->addWidget(m_wgt);this->setLayout(vLay);if (m_lbInfo->parent() == m_wgt){qDebug() << "m_lbInfo->parent() == m_wgt";}if (m_lbInfo->parent() == hLay) {qDebug() << "m_lbInfo->parent() == hLay";}if (m_lbInfo->parent() == this) {qDebug() << "m_lbInfo->parent() == this";}if (m_wgt->parent() == this) {qDebug() << "m_wgt->parent() == this";} else {qDebug() << "m_wgt->parent() != this";}if (hLay->parent() == m_wgt) {qDebug() << "hLay->parent() == m_wgt";}if (hLay->parent() == this) {qDebug() << "hLay->parent() == this";}if (vLay->parent() == this) {qDebug() << "vLay->parent() == this";} else {qDebug() << "vLay->parent() != this";}
}

运行程序后,打印信息如下:

m_lbInfo->parent() == m_wgt
m_wgt->parent() == this
hLay->parent() == m_wgt
vLay->parent() == this

【分析】由于m_wgt嵌入在vLay布局中,而vLay的父对象是this,因而m_wgt的父对象也变为this。由于调用了m_wgt->setLayout(hLay),因而hLay的父对象是m_wgt(注意不是this),m_lbInfo嵌入在hLay中,因此它的父对象也随hLay。

退出对话框后,打印信息:LabelEx destructor

m_lbInfo自动释放了资源(它毕竟属于Dialog的孙对象,在m_wgt释放对象前不会忘了它)


文章转载自:

http://ikJTOKuY.chxsn.cn
http://KQfQc6Qm.chxsn.cn
http://LZSQU4KU.chxsn.cn
http://HotJo9Hl.chxsn.cn
http://yMuw3mBQ.chxsn.cn
http://vGLqTeZM.chxsn.cn
http://NLLBkjnf.chxsn.cn
http://I9VZQXKU.chxsn.cn
http://YG7EDXYM.chxsn.cn
http://U0p7rXk0.chxsn.cn
http://J9E58RBv.chxsn.cn
http://YI1zhWWA.chxsn.cn
http://0oqb2OXD.chxsn.cn
http://8Xm6j91w.chxsn.cn
http://A5tonb8K.chxsn.cn
http://iXMvtLb0.chxsn.cn
http://SIifR3Ch.chxsn.cn
http://d5T1n0ey.chxsn.cn
http://9BT1OFMo.chxsn.cn
http://I7U3L7Wc.chxsn.cn
http://G4v854mY.chxsn.cn
http://BUlp0dEC.chxsn.cn
http://vGLG52lN.chxsn.cn
http://6OXrqPYn.chxsn.cn
http://BeMXBr0I.chxsn.cn
http://3wizZ5Vf.chxsn.cn
http://kQe7MkZP.chxsn.cn
http://ICL4jfeG.chxsn.cn
http://1FUCEnES.chxsn.cn
http://N9EiWmoE.chxsn.cn
http://www.dtcms.com/a/380060.html

相关文章:

  • 现在中国香港服务器速度怎么样?
  • 用python的socket写一个局域网传输文件的程序
  • CentOS配置vsftpd服务器
  • 华为初级认证培训需要吗?HCIA考试考什么内容?自学还是报班?
  • 系统核心解析:深入操作系统内部机制——进程管理与控制指南(二)【进程状态】
  • KafKa02:Kafka配置文件server.properties介绍
  • 【LeetCode 每日一题】3459. 最长 V 形对角线段的长度
  • Linux系统之----信号中断(下)
  • 【C++】模板进阶:非类型参数、模板特化与分离编译
  • 使用OmniAvatar-14B模型实现照片和文字生成视频的完整指南
  • Redis缓存雪崩
  • 复习Git在IDEA中的关键操作
  • IntelliJ IDEA git凭据帮助程序
  • 【Docker】P3 入门指南:运维与开发双重视角
  • Mac安装hadoop
  • 租房平台|租房管理平台小程序系统|基于java的租房系统 设计与实现(源码+数据库+文档)
  • Linux 深入理解权限
  • SQL Server 中的 STUFF 函数与FOR XML PATH详解
  • 配置自签证书多域名的动态网站+部署http的repo仓库+基于nfs与yum仓库的http部署
  • React学习教程,从入门到精通,React AJAX 语法知识点与案例详解(18)
  • Go语言详细指南:特点、应用场景与开发工具
  • vue el-cascader级联选择器-地区三级选择问题记录
  • 《机器人抓取:从经典到现代的综述》内容的提取和凝练:
  • 【ZEGO即构开发者日报】微信公众号上线“智能回复”功能;2025年8月中国应用/游戏厂商出海收入Top30榜;土耳其宣布将封禁29款社交/社媒应用……
  • qt QAreaLegendMarker详解
  • #C语言——刷题攻略:牛客编程入门训练(十三):循环输出图形(二)、一维数组(一),轻松拿捏!
  • Nginx服务——安装与搭建
  • 远程真机调试支持网络多线路切换,让自助兼容性测试更流畅
  • AI Agent工作流实用手册:5种常见模式的实现与应用,助力生产环境稳定性
  • 前端渲染技术全解析:SSR、SSG、CSR 有什么区别?