您必须首先删除现有的布局管理器(由 layout()),然后才能使用新布局调用 setLayout()。
来自 http://doc.qt.io/qt-5.9/qwidget.html#setLayout
哪个函数用于删除之前的布局?
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;
你只需使用
delete layout;
就像使用
new
创建的任何其他指针一样。
此代码删除布局、其所有子布局以及布局内的所有内容“消失”。
qDeleteAll(yourWidget->findChildren<QWidget *>(QString(), Qt::FindDirectChildrenOnly));
delete layout();
这将删除小部件 yourWidget
的所有
direct小部件。使用
Qt::FindDirectChildrenOnly
是必要,因为它可以防止删除同样在列表中并且可能已被 qDeleteAll
内的循环删除的小部件的子小部件。
以下是
qDeleteAll
的描述:
void qDeleteAll(ForwardIterator 开始,ForwardIterator 结束)
使用 C++ 删除 > 运算符删除 [begin, end] 范围内的所有项目。 item 类型必须是指针类型(例如 QWidget *)。
请注意,需要使用该小部件(而不是布局)中的容器来调用
qDeleteAll
。请注意,qDeleteAll
不会删除 yourWidget
- 只是删除它的子项。
现在可以设置新的布局了。
我想删除当前布局,将其替换为新布局,但保留该布局管理的所有小部件。我发现在这种情况下,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;
}
}
来自 Qt6 的文档:
以下代码片段显示了从布局中删除所有项目的安全方法:
QLayoutItem *child;
while ((child = layout->takeAt(0)) != nullptr) {
...
delete child->widget(); // delete the widget
delete child; // delete the layout item
}
这假设 takeAt() 已在 QLayout 子类中正确实现。请点击链接了解详情。
我今天遇到了一个问题,我试图删除一个小部件的布局以将其替换为另一个小部件。发生的情况是,尽管调用了
delete layout();
,之前的布局从未消失。
因此,我利用布局不能有多个父级并且可以重新设置父级这一事实,想出了一种非常简单、有效且受支持的解决方法。
我创建了一个
deletePreviousLayout
函数:
void MyWidget::deletePreviousLayout()
{
QWidget dummyWidget; // On the stack to deallocate it at the end of the function.
dummyWidget.setLayout(layout()); // Reparenting
}
就是这样。