在pyqt中清除布局中的所有控件
有没有办法清空(删除)布局中的所有小部件?
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
中的所有小部件?我没有找到这样的办法。
14 个回答
30
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)
你就不会遇到这个问题了。
42
这可能有点晚了,但我想为将来参考补充一下:
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()
循环时会遇到问题的原因。
136
经过大量的研究(这花了我不少时间,所以我把它记录下来以备将来参考),我找到了一种真正清除和删除布局中小部件的方法:
for i in reversed(range(layout.count())):
layout.itemAt(i).widget().setParent(None)
文档中关于QWidget的说明是:
当父级被删除时,新小部件也会被删除。
重要提示:你需要反向循环,因为从开头删除东西会导致其他项目的位置发生变化,从而改变布局中项目的顺序。
要测试并确认布局是否为空:
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)
将这个对象安排为待删除。
然而,如果你运行上面指定的测试代码,它会打印出一些值。这表明布局中仍然有项目,而不是使用setParent的代码。