【问题标题】:Issue regarding setting parent of widget in Qt关于在 Qt 中设置小部件父级的问题
【发布时间】:2021-09-01 19:27:15
【问题描述】:

来自this post这里,一般来说:

所有 QObject 都会自动删除它们自己的子对象。 (看 docs 这里。)QWidgets 是 QObjects。所以只要你建立一个 父/子关系,您不需要手动删除您的 对象。为此,只需将指向父对象的指针传递给 构造函数:

QLabel *label1 = new QLabel;   // <<- NEED TO DELETE
QLabel *label2 = new QLabel(some_parent_obj);   // Will be deleted when some_parent_obj is deleted

所以出现了一些问题:

  1. 每个小部件都需要需要/需要父级吗?如果不是,有哪些例外?如果是,那么 没有 父级的小部件会发生什么情况?

我问这个是因为从 Qt Docs 中的示例中,一些示例小部件有父级 (QLabel example),但有些没有(QBarChart example,还有QFontQColor 等...)。

所以我想知道是否有例外,这些小部件不需要任何父母,如果我出于某种原因使用new 声明它们, 之后我必须delete

反之亦然……

  1. 没有父级保证的小部件是否会在其所在的小部件(不一定是其父级)被删除时导致内存泄漏(或类似情况)?或者如果它从布局中删除而没有发生任何删除?

因为根据我的代码经验,我创建了可能相当多(~100)的小部件和其他东西,既没有设置任何父级(也没有在之后使用delete),而且项目似乎运行良好,没有即使在一段时间后也会出现任何停顿(虽然效果可能是潜在的,因为我没有运行 Memcheck),因此这个问题就在这里。

【问题讨论】:

    标签: qt memory-management memory-leaks parent-child new-operator


    【解决方案1】:

    是否每个必要的小部件都需要/需要父级?

    如果您希望它们被自动删除 - 是的。但是……

    如果不是,有哪些例外情况?如果是,没有父级的小部件会怎样?

    如果您使用QLayout::addWidget 将小部件附加到布局,则无需为小部件提供父级。如果你查看source code,你会看到当你这样做时,它会自动将布局的父级附加为小部件的父级(除非你没有将布局附加到任何小部件)。

    但是,如果您让使用new 创建的小部件没有父级并且不附加到任何东西 - 它会泄漏内存。您必须使用deleteQObject::deleteLater 将其删除。当对象有任何连接时,建议使用最后一个选项。

    当它所在的小部件(不一定是它的父级)被删除时,没有父级的小部件是否保证会导致内存泄漏(或类似的事情)?或者如果它从布局中删除而没有发生任何删除?

    正如我已经提到的 QLayout::addWidget 为添加的小部件设置父级,所以答案是否定的。另请注意,当您调用QLayout::removeWidget 时,它只会从布局中删除QLayoutItem,但小部件的父级保持与调用QLayout::addWidget 后相同。

    【讨论】:

    • 有趣。另一个问题:内存泄漏会发生什么?它们最终会被清理吗(如果是,那么什么时候?)?或者他们会在达到限制时使应用程序崩溃(以及之后会发生什么)?
    • 使用new 分配的内存会在应用程序关闭/崩溃时被清理,无论它是什么,或者当您使用deletedeleteLater 明确这样做时(以​​防QObject 实体)。如果内存不断泄漏,可能会导致崩溃——通过new 创建一个对象,不要显式或隐式删除它。如果程序运行时间足够长,最终会导致内存不足。
    • 如果我将QHBoxLayout 附加到QWidget(可能带有setLayout()),然后删除QWidgetQHBoxLayout 将被同时销毁,对吗?
    • 是的,正确的。 QWidget::seLayout as QLayout::addWidget 为添加的对象设置父级。在这种情况下,QWidget::setLayout 将调用类似layout-&gt;setParent(this) 的名称。 Source code.
    猜你喜欢
    • 2011-04-15
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    相关资源
    最近更新 更多