清除pyq中布局中的所有小组件

2024-04-28 08:56:05 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有办法清除(删除)布局中的所有小部件?

self.plot_layout = QtGui.QGridLayout()
self.plot_layout.setGeometry(QtCore.QRect(200,200,200,200))
self.root_layout.addLayout(self.plot_layout)
self.plot_layout.addWidget(MyWidget())

现在我想用一个新的小部件替换plot_layout中的小部件。有没有一种简单的方法清除plot_layout中的所有小部件?我看没有这样的方法。


Tags: 方法selfplot部件root布局layout办法
3条回答

这可能有点晚了,但只是想添加此内容以供将来参考:

def clearLayout(layout):
  while layout.count():
    child = layout.takeAt(0)
    if child.widget():
      child.widget().deleteLater()

改编自Qt文档http://doc.qt.io/qt-5/qlayout.html#takeAt。请记住,在while或for循环中从布局中移除子项时,实际上是在修改布局中每个子项的索引。这就是为什么使用for i in range()循环会遇到问题的原因。

如果您不需要在布局中添加新的小部件,那么PALEN的答案很好。

for i in reversed(range(layout.count())): 
    layout.itemAt(i).widget().setParent(None)

但是,如果清空并多次填充布局或使用许多小部件填充布局,则在某些时候会出现“分段错误(核心转储)”。布局似乎保留了一个小部件列表,并且该列表的大小受到限制。

如果这样删除小部件:

for i in reversed(range(layout.count())): 
    widgetToRemove = layout.itemAt(i).widget()
    # remove it from the layout list
    layout.removeWidget(widgetToRemove)
    # remove it from the gui
    widgetToRemove.setParent(None)

你不会有那个问题的。

经过大量的研究(这次花了很长时间,所以我把它添加到这里以供将来参考),我发现这样才能真正清除和删除布局中的小部件:

for i in reversed(range(layout.count())): 
    layout.itemAt(i).widget().setParent(None)

文档中关于QWidget的内容是:

The new widget is deleted when its parent is deleted.

重要提示:您需要向后循环,因为从开始处删除内容会转移项目并更改布局中项目的顺序。

要测试并确认布局为空:

for i in range(layout.count()): print i

似乎还有别的办法。不要使用setParent函数,而是使用deleteLater()函数,如下所示:

for i in reversed(range(layout.count())): 
    layout.itemAt(i).widget().deleteLater()

文档说明QObject.deleteLater(self)

Schedules this object for deletion.

但是,如果运行上面指定的测试代码,它将打印一些值。这表示布局仍有项,而不是带有setParent的代码。

相关问题 更多 >