Qt中的亲子关系

时间:2015-10-22 09:31:33

标签: c++ qt parent-child

我想澄清在new创建子项时如何删除子项的概念。

此代码示例来自http://doc.qt.io/qt-4.8/qsignalmapper.html

ButtonWidget::ButtonWidget(QStringList texts, QWidget *parent)
    : QWidget(parent)
{
    signalMapper = new QSignalMapper(this);

    QGridLayout *gridLayout = new QGridLayout;
    for (int i = 0; i < texts.size(); ++i) {
        QPushButton *button = new QPushButton(texts[i]);
        connect(button, SIGNAL(clicked()), signalMapper, SLOT(map()));
        signalMapper->setMapping(button, texts[i]);
        gridLayout->addWidget(button, i / 3, i % 3);
    }

    connect(signalMapper, SIGNAL(mapped(const QString &)),
            this, SIGNAL(clicked(const QString &)));

    setLayout(gridLayout);
}
  1. signalMapper

    由于它是使用参数this构造的,当删除父对象ButtonWidget时,它也会被删除。

    这是对的吗?

  2. gridLayout

    为什么gridLayout不需要创建new QGridLayout(this)

  3. button

    它是在for循环中创建的,这意味着它在每个循环后都将超出范围。在正常情况下,如果在循环内没有删除,则应该有内存泄漏。那么,这个程序会导致内存泄漏吗?

1 个答案:

答案 0 :(得分:5)

  1. 是。为QObject指定父级时,它将获得该对象的所有权。删除父对象时,它将删除它的所有子对象(它拥有的所有对象);
  2. 原因是setLayout为窗口小部件设置布局将此布局的所有权赋予窗口小部件。因此,在调用setLayout之后,网格布局由ButtonWidget拥有,并在需要时删除它(即当ButtonWidget本身将被删除时);
  3. 与2相同,调用gridLayout->addWidget(button, i / 3, i % 3);后,button的所有权将发生变化。从技术上讲,addWidget会调用addItem,因此会创建QWidgetItem。布局取得的所有权,父窗口小部件取得小部件的所有权。无论如何,按钮将在销毁它的父窗口小部件时销毁。