验证布局中的控件的父窗口
- 概述
- 示例
- 开发环境
- 项目
- 运行结果
- 结论
- 番外
概述
平时在创建一个窗口类的子空间时,一般需要先创建布局,将子控件添加到窗口的布局中。子控件没有显示的指定父窗口时,那么这个布局中的控件的父窗口是布局还是这个窗口类呢。
本文围绕这个问题展开验证。采用一个简单的小程序。
下面要实现的小程序,其窗口类中有一个布局,布局中添加了一个控件。大体结构如下图所示。
示例
开发环境
在QtCreate4.11.2,基于qt 5.14.2的界面应用程序。
项目
main.cpp
#include "dialog.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Dialog w;w.show();return a.exec();
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACEclass Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();
protected:void initUi();
private:Ui::Dialog *ui;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QString>
#include <QDebug>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog)
{ui->setupUi(this);initUi();createJsonFile();readJsonFile();
}Dialog::~Dialog()
{delete ui;
}
void Dialog::initUi()
{QPushButton *pBtn = new QPushButton("hdu");QHBoxLayout *hLayout = new QHBoxLayout(this);hLayout->addWidget(pBtn);QObject *layoutParent =hLayout->parent();QObject* btnParent = pBtn->parent();if(btnParent == (QObject*)hLayout){qDebug("=====layout is btn's parent!");}char str[20]={0};char *p = str;sprintf(str, "0x%x", (unsigned int)btnParent);QString strAddress = QString::fromUtf8(p);qDebug("btn parent address:%s",qPrintable(strAddress));//0xa4d4f990sprintf(str, "0x%x", (unsigned int)hLayout);QString strLayoutAddress = QString::fromUtf8(p);qDebug("layout address:%s",qPrintable(strLayoutAddress));//0xf1f7d7c0sprintf(str, "0x%x", (unsigned int)layoutParent);QString strLayoutParentAddress = QString::fromUtf8(p);qDebug("layout parent address:%s",qPrintable(strLayoutParentAddress));//0xa4d4f990
}
运行结果
结论
由上面的运行结果可知:添加到布局中的控件的父控件是其所在布局的父窗口,即当前的窗口类。
番外
作者创建控件的时候未指定父对象,然后将其加入到布局中。根据qt对象树(其内存管理机制),当前类的子控件是没有必要手动去释放的,即调用delete去删除控件的,因为作者认为创建的子控件虽没有显示指定其父对象,但是布局是当前类的,子控件又加入了布局,故而子控件也归当前类所属,子控件的父窗口为子控件所加入的布局的父窗口。此为验证布局中的控件其父对象,不需要手动释放加入窗口类布局的子控件。