Qt 中父子关系使用总结

背景

Qt 中到父子关系和类的继承无关,仅表示对象间到从属关系;继承自 QObject 的对象在构造时需要指定父对象指针:

#include 
#include "QDebug"

class QtClassDemo : public QObject
{
  Q_OBJECT

public:
  QtClassDemo(QObject *parent) : QObject(parent) {};
  ~QtClassDemo()
  {
    qDebug() << QString("%1析构").arg(this->property("objectName").toString());
  };
};

设置父对象

①.概述

继承自 QObject 的对象在构造时需要传入父对象指针,会自动在其子对象列表中会增加该子对象指针。

②.代码示例

qDebug() << "创建父对象";
QtClassDemo * parrentObj = new QtClassDemo(this);
parrentObj->setProperty("objectName", "父对象");
qDebug() << QString("子对象数量:%1").arg(parrentObj->children().size()) << endl;
    
qDebug() << "创建子对象1";
QtClassDemo * childObj1 = new QtClassDemo(parrentObj);
childObj1->setProperty("objectName", "子对象1");
qDebug() << QString("子对象数量:%1").arg(parrentObj->children().size()) << endl;

qDebug() << "创建子对象2";
QtClassDemo * childObj2 = new QtClassDemo(parrentObj);
childObj2->setProperty("objectName", "子对象2");
qDebug() << QString("子对象数量:%1").arg(parrentObj->children().size()) << endl;
  
qDebug() << "遍历所有子对象:";
for ( auto & child : parrentObj->children())
{
  qDebug() << child;
}

Qt 中父子关系使用总结_第1张图片

删除子对象

①.概述

继承自 QObject 的对象在析构时,会自动在其父对象到子节点列表中会删除该对象指针。

②.代码示例

qDebug() << "创建父对象";
QtClassDemo * parrentObj = new QtClassDemo(this);
parrentObj->setProperty("objectName", "父对象");
qDebug() << QString("子对象数量:%1").arg(parrentObj->children().size()) << endl;
  
qDebug() << "创建子对象1";
QtClassDemo * childObj1 = new QtClassDemo(parrentObj);
childObj1->setProperty("objectName", "子对象1");
qDebug() << QString("子对象数量:%1").arg(parrentObj->children().size()) << endl;

qDebug() << "创建子对象2";
QtClassDemo * childObj2 = new QtClassDemo(parrentObj);
childObj2->setProperty("objectName", "子对象2");
qDebug() << QString("子对象数量:%1").arg(parrentObj->children().size()) << endl;
  
qDebug() << "遍历所有子对象:";
for ( auto & child : parrentObj->children())
{
  qDebug() << child;
}

qDebug() <<endl << "删除子对象1" << endl;
delete childObj1; childObj1 = nullptr;

qDebug() << "遍历所有子对象:";
for (auto & child : parrentObj->children())
{
  qDebug() << child;
}

Qt 中父子关系使用总结_第2张图片

删除父对象

①.概述

继承自 QObject 的对象在删除时,会自动删除其子对象列表中的所有对象。

②.代码示例

qDebug() << endl << "创建父对象";
QtClassDemo * parrentObj = new QtClassDemo(this);
parrentObj->setProperty("objectName", "父对象");
  
qDebug() << endl << "创建子对象1";
QtClassDemo * childObj1 = new QtClassDemo(parrentObj);
childObj1->setProperty("objectName", "子对象1");

qDebug() << endl << "创建子对象2";
QtClassDemo * childObj2 = new QtClassDemo(parrentObj);
childObj2->setProperty("objectName", "子对象2");
  

qDebug() << endl << "遍历所有子对象:";
for ( auto & child : parrentObj->children())
{
  qDebug() << child;
}

qDebug() << endl << "删除父对象" << endl;
delete parrentObj; parrentObj = nullptr;

Qt 中父子关系使用总结_第3张图片

查找子对象

①.概述

继承自 QObject 的对象可以根据名称对其子对象进行查找。

②.查找单个子对象

qDebug() << endl << "创建父对象";
QtClassDemo * parrentObj = new QtClassDemo(this);
parrentObj->setProperty("objectName", "父对象");
  
qDebug() << endl << "创建子对象1";
QtClassDemo * childObj1 = new QtClassDemo(parrentObj);
childObj1->setProperty("objectName", "子对象1");

qDebug() << endl << "创建子对象2";
QtClassDemo * childObj2 = new QtClassDemo(parrentObj);
childObj2->setProperty("objectName", "子对象2");
  
qDebug() << endl << "查找子对象2:";
QtClassDemo * child = parrentObj->findChild<QtClassDemo *>("子对象2");
if( child)
  qDebug() << "查找成功," << child;

Qt 中父子关系使用总结_第4张图片

③.查找多个子对象

qDebug() << endl << "创建父对象";
QtClassDemo * parrentObj = new QtClassDemo(this);
parrentObj->setProperty("objectName", "父对象");
  
qDebug() << endl << "创建子对象1";
QtClassDemo * childObj1 = new QtClassDemo(parrentObj);
childObj1->setProperty("objectName", "子对象1");

qDebug() << endl << "创建子对象2";
QtClassDemo * childObj2 = new QtClassDemo(parrentObj);
childObj2->setProperty("objectName", "子对象2");
  
qDebug() << endl << "查找所有 QtClassDemo 类型到子对象:";
for (auto & child : parrentObj->findChildren<QtClassDemo *>())
{
  qDebug()  << child;
}

Qt 中父子关系使用总结_第5张图片

移动工作线程

①.概述

继承自 QObject 的对象可以通过 moveToThread 更改工作线程。

②.存在父对象则不允许移动

QtClassDemo * demoObj = new QtClassDemo(this);
QThread  * thread = new QThread;
demoObj->moveToThread(thread);

Qt 中父子关系使用总结_第6张图片

③.子对象跟随父对象一起移动

qDebug() << endl << "创建父对象";
QtClassDemo * parrentObj = new QtClassDemo(nullptr);
parrentObj->setProperty("objectName", "父对象");

qDebug() <<  "创建子对象1";
QtClassDemo * childObj1 = new QtClassDemo(parrentObj);
childObj1->setProperty("objectName", "子对象1");

qDebug() <<  "创建子对象2";
QtClassDemo * childObj2 = new QtClassDemo(parrentObj);
childObj2->setProperty("objectName", "子对象2");

qDebug() << endl << "移动工作线程";
QThread  * thread = new QThread;
parrentObj->moveToThread(thread);

qDebug() << "当前线程:" << this->thread();
qDebug() << "父对象线程:" << parrentObj->thread();
qDebug() << "子对象1线程:" << childObj1->thread();
qDebug() << "子对象2线程:" << childObj2->thread();

Qt 中父子关系使用总结_第7张图片

父子关系注意事项

①.概述

继承自 QObject 的对象在删除时会自动删除其子对象,因此需要确保对象的删除顺序。

②.父对象删除后子对象指针并不为空

由于父对象删除后子对象指针并不为空,因此需要注意可能存在再次使用的情况。

qDebug() << endl << "创建父对象";
QtClassDemo * parrentObj = new QtClassDemo(nullptr);
parrentObj->setProperty("objectName", "父对象");

qDebug() <<  "创建子对象1";
QtClassDemo * childObj1 = new QtClassDemo(parrentObj);
childObj1->setProperty("objectName", "子对象1");

qDebug() <<  "创建子对象2";
QtClassDemo * childObj2 = new QtClassDemo(parrentObj);
childObj2->setProperty("objectName", "子对象2");

qDebug() << endl << "删除父对象" << endl;
delete parrentObj; parrentObj = nullptr;

qDebug() << endl << "childObj1 ;" << static_cast<void*>(childObj1);

Qt 中父子关系使用总结_第8张图片

③.防止多次删除对象

由于父对象删除后子对象会自动删除,因此需要注意重复删除到情况,如栈对象、智能指针等自动管理到对象。

qDebug() << endl << "创建父对象";
QtClassDemo * parrentObj = new QtClassDemo(nullptr);
parrentObj->setProperty("objectName", "父对象");

qDebug() <<  "创建子对象1";
QtClassDemo * childObj1 = new QtClassDemo(parrentObj);
childObj1->setProperty("objectName", "子对象1");
  
QSharedPointer<QtClassDemo> p = QSharedPointer<QtClassDemo>(childObj1);
  
qDebug() <<  "创建子对象2";
QtClassDemo * childObj2 = new QtClassDemo(parrentObj);
childObj2->setProperty("objectName", "子对象2");

qDebug() << endl << "删除父对象" << endl;
delete parrentObj; parrentObj = nullptr;

Qt 中父子关系使用总结_第9张图片

布局管理器和父子关系

①.给布局管理器指定父对象

在创建布局管理器时,若直接指定类父对象,则相当于对父对象执行了 setLayout 方法。

qDebug() << "初始的布局管理器:" << this->layout();
QHBoxLayout * layout = new QHBoxLayout(this);
qDebug() << "创建的布局管理器:" << layout;
qDebug() << "当前的布局管理器:" << this->layout();

Qt 中父子关系使用总结_第10张图片

②.布局管理器默认给其管理到对象添加父对象

qDebug() << "this 指针:" << this;
QHBoxLayout * layout = new QHBoxLayout();
QPushButton * thn = new QPushButton;
layout->addWidget(thn);
qDebug() << "thn 父对象指针:" << thn->parent();
this->setLayout(layout);
qDebug() << "thn 父对象指针:" << thn->parent();

Qt 中父子关系使用总结_第11张图片

QWidget 和父子关系

①.概述

qwidget 对 QObject 的父子关系进行类扩充,可以根据位置查找其子对象。

②.代码示例

QHBoxLayout * layout = new QHBoxLayout(this);
QLabel * label1 = new QLabel("标签1",this);
label1->setObjectName("标签1");
QLabel * label2 = new QLabel("标签2", this);
label2->setObjectName("标签2");
QLabel * label3 = new QLabel("标签3", this);
label3->setObjectName("标签3");
layout->addWidget(label1);
layout->addWidget(label2);
layout->addWidget(label3);

void QtGuiApplication1::mousePressEvent(QMouseEvent *event)
{
  auto child = this->childAt(event->x(), event->y());
  if (child)
    qDebug() << child;
}

Qt 中父子关系使用总结_第12张图片
Qt 中父子关系使用总结_第13张图片

你可能感兴趣的:(Qt,qt,c++)