我试图找到一些需要qt布局的东西并从中删除所有内容。想象一下窗口的样子 - 我有:
QVBoxLayout
| ------QHboxLayout
|---------QWidget
| ------QHboxLayout
|---------QWidget
.........
所以我需要一些东西,我可以递归地调用CLEAR AND DELETE来自我的父QVBoxLayout
的所有东西。我尝试了这里提到的事情(Clear all widgets in a layout in pyqt),但没有一个工作(无论如何都没有正确答案)。我的代码如下所示:
def clearLayout(self, layout):
for i in range(layout.count()):
if (type(layout.itemAt(i)) == QtGui.QHBoxLayout):
print "layout " + str(layout.itemAt(i))
self.clearLayout(layout.itemAt(i))
else:
print "widget" + str(layout.itemAt(i))
layout.itemAt(i).widget().close()
但是它给出了一个错误:
layout.itemAt(i).widget().close()
AttributeError: 'NoneType' object has no attribute 'close'
=>编辑
这种方式有效(但如果还有其他Layout
而不是HBoxLayout
则不会:
def clearLayout(self, layout):
layouts = []
for i in range(layout.count()):
if (type(layout.itemAt(i)) == QtGui.QHBoxLayout):
print "layout " + str(layout.itemAt(i))
self.clearLayout(layout.itemAt(i))
layouts.append(layout.itemAt(i))
else:
print "widget" + str(layout.itemAt(i))
if (type(layout.itemAt(i)) == QtGui.QWidgetItem):
layout.itemAt(i).widget().close()
答案 0 :(得分:13)
清除布局最安全的方法是使用takeAt方法提取项目,然后使用deleteLater显式删除任何小部件:
def clearLayout(self, layout):
if layout is not None:
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.deleteLater()
else:
self.clearLayout(item.layout())
答案 1 :(得分:7)
您的代码问题QLayout.itemAt()
会返回QLayoutItem
,QWidgetItem
或QSpacerItem
,具体取决于该位置的项目。所以条件:
type(layout.itemAt(i)) == QtGui.QHBoxLayout
永远不会是True
,您将尝试.widget()
QLayoutItem
并返回None
。因此你得到的错误。另一件事是,你需要向后循环。因为从头开始删除东西会改变项目并改变项目的顺序。
你需要像这样编写你的函数:
def clearLayout(self, layout):
for i in reversed(range(layout.count())):
item = layout.itemAt(i)
if isinstance(item, QtGui.QWidgetItem):
print "widget" + str(item)
item.widget().close()
# or
# item.widget().setParent(None)
elif isinstance(item, QtGui.QSpacerItem):
print "spacer " + str(item)
# no need to do extra stuff
else:
print "layout " + str(item)
self.clearLayout(item.layout())
# remove the item from layout
layout.removeItem(item)