如何删除小部件上已经存在的布局?

Posted

技术标签:

【中文标题】如何删除小部件上已经存在的布局?【英文标题】:How to delete an already existing layout on a widget? 【发布时间】:2011-09-23 12:06:32 【问题描述】:

您必须先删除现有的布局管理器(由 layout()) 在您可以使用新布局调用 setLayout() 之前。

来自http://doc.qt.io/qt-5.9/qwidget.html#setLayout

哪个函数用于删除之前的布局?

【问题讨论】:

【参考方案1】:

Chris Wilson 的回答是正确的,但我发现布局不会删除其下方的子布局和 qwidgets。如果您有复杂的布局或可能存在内存泄漏,最好手动执行。

QLayout * layout = new QWhateverLayout();

// ... create complicated layout ...

// completely delete layout and sublayouts
QLayoutItem * item;
QLayout * sublayout;
QWidget * widget;
while ((item = layout->takeAt(0))) 
    if ((sublayout = item->layout()) != 0) /* do the same for sublayout*/
    else if ((widget = item->widget()) != 0) widget->hide(); delete widget;
    else delete item;


// then finally
delete layout;

【讨论】:

我认为这是不正确的,因为如果您在其构造函数中传递父级,它将删除子级和子布局。 您是否发现在删除之前隐藏小部件有什么好处,或者您只是想确定一下?我问是因为我使用删除而不隐藏,并且会对即将出现的副作用感兴趣【参考方案2】:

你只是使用

delete layout;

就像使用 new 创建的任何其他指针一样。

【讨论】:

这会造成内存泄漏,请参阅 perden 的回答【参考方案3】:

我想删除当前布局,将其替换为新布局,但保留由该布局管理的所有小部件。我发现在这种情况下,Chris Wilson 的解决方案效果不佳。布局并不总是改变。

这对我有用:

void RemoveLayout (QWidget* widget)

    QLayout* layout = widget->layout ();
    if (layout != 0)
    
    QLayoutItem *item;
    while ((item = layout->takeAt(0)) != 0)
        layout->removeItem (item);
    delete layout;
    

【讨论】:

你应该删除项目;在 layout->removeItem (item) 之后;否则您的程序中会出现内存泄漏。查看 perden 答案。【参考方案4】:

此代码删除布局、其所有子级以及布局内的所有内容“消失”。

qDeleteAll(yourWidget->findChildren<QWidget *>(QString(), Qt::FindDirectChildrenOnly));
delete layout();

这将删除小部件yourWidget 的所有直接小部件。使用Qt::FindDirectChildrenOnly必要的,因为它可以防止删除作为也在列表中的小部件的子小部件,并且可能已经被qDeleteAll 内的循环删除。

这里是qDeleteAll的描述:

void qDeleteAll(ForwardIterator begin, ForwardIterator end)

使用 C++ 删除 > 运算符删除范围 [begin, end] 中的所有项目。项类型必须是指针类型(例如,QWidget *)。

请注意,qDeleteAll 需要使用来自该小部件(而不是布局)的容器调用。请注意,qDeleteAll 不会删除 yourWidget - 只是它的子级。

现在可以设置新的布局了。

【讨论】:

这种方法的问题是你可能会不小心删除一些附加的QObjectyourWidget 与布局/小部件结构无关,这个问题可能很难找到。 但是您可以过滤类型(在这种情况下为 QWidget*),并且您始终可以在找到子项后执行另一层过滤。我认为这是一个很好的解决方案

以上是关于如何删除小部件上已经存在的布局?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确删除小部件并更新/重新加载小部件

QT:如何在布局中动态添加和删除小部件?

如何在 Flutter 布局中添加或删除组件?

添加/删除包含多个小部件pyqt的布局

如何从另一个 Qwidget 中删除小部件?

如何从 Android 中的 RemoteViews 中删除小部件?