清除pyqt中布局中的所有小部件

Fal*_*rri 38 python qt pyqt pyqt4

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

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())
Run Code Online (Sandbox Code Playgroud)

现在我想plot_layout用新的小部件替换小部件.是否有一种简单的方法可以清除所有小部件plot_layout?我没有看到任何这样的方法.

PAL*_*LEN 74

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

for i in reversed(range(layout.count())): 
    layout.itemAt(i).widget().setParent(None)
Run Code Online (Sandbox Code Playgroud)

文档中关于QWidget的内容是:

删除其父窗口时将删除新窗口小部件.

重要说明:您需要向后循环,因为从开头删除项目会更改项目并更改布局中项目的顺序.

要测试并确认布局为空:

for i in range(layout.count()): print i
Run Code Online (Sandbox Code Playgroud)

似乎有另一种方法可以做到这一点.而不是使用setParent函数,使用deleteLater()函数,如下所示:

for i in reversed(range(layout.count())): 
    layout.itemAt(i).widget().deleteLater()
Run Code Online (Sandbox Code Playgroud)

文档说QObject.deleteLater(个体经营)

安排此对象进行删除.

但是,如果运行上面指定的测试代码,则会打印一些值.这表明布局仍然具有项目,而不是具有setParent的代码.

  • 你应该使用`takeAt()`而不是`itemAt()`.`takeAt()`还将从QBoxLayout中移除间隔符/伸展(没有父节点):`widget = layout.takeAt(i).widget(); 如果widget不是None:widget.setParent(None)` (3认同)

小智 22

这可能有点太晚,但只是想添加它以供将来参考:

def clearLayout(layout):
  while layout.count():
    child = layout.takeAt(0)
    if child.widget():
      child.widget().deleteLater()
Run Code Online (Sandbox Code Playgroud)

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


Bla*_*hor 19

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

for i in reversed(range(layout.count())): 
    layout.itemAt(i).widget().setParent(None)
Run Code Online (Sandbox Code Playgroud)

但是,如果您多次清空并填充布局或使用许多小部件,您将在某些时候获得"分段错误(核心转储)".似乎布局保留了窗口小部件列表,并且此列表的大小有限.

如果您以这种方式删除小部件:

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)
Run Code Online (Sandbox Code Playgroud)

你不会遇到那个问题.

  • `setParent(None)` 不会删除小部件。请参阅我对 Palens 答案的评论和答案。这也是“分段错误”的原因。请改用“deleteLater()”。 (2认同)

use*_*214 11

这就是我清除布局的方式:

def clearLayout(layout):
    if layout != None:
        while layout.count():
            child = layout.takeAt(0)
            if child.widget() is not None:
                child.widget().deleteLater()
            elif child.layout() is not None:
                clearLayout(child.layout())
Run Code Online (Sandbox Code Playgroud)


Vol*_*nko 10

您可以使用以下close()方法widget:

for i in range(layout.count()): layout.itemAt(i).widget().close()
Run Code Online (Sandbox Code Playgroud)


Sol*_*lot 7

我用:

    while layout.count() > 0: 
        layout.itemAt(0).setParent(None)
Run Code Online (Sandbox Code Playgroud)