从布局中删除所有项目
Posted
技术标签:
【中文标题】从布局中删除所有项目【英文标题】:Remove all items from a layout 【发布时间】:2012-02-21 08:04:12 【问题描述】:我试图找到可以采用 qt 布局并从中删除所有内容的东西。只是想象一下窗口的样子 - 我有:
QVBoxLayout
| ------QHboxLayout
|---------QWidget
| ------QHboxLayout
|---------QWidget
.........
所以我需要一些可以递归调用的东西来清除和删除我父母 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()
【问题讨论】:
【参考方案1】:清除布局最安全的方法是使用 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())
【讨论】:
这是一个更优雅的解决方案。谢谢【参考方案2】:您的代码的问题是 QLayout.itemAt()
返回 QLayoutItem
、QWidgetItem
或 QSpacerItem
,具体取决于该位置的项目。所以条件:
type(layout.itemAt(i)) == QtGui.QHBoxLayout
永远不会是True
,您将尝试为QLayoutItem
执行.widget()
并返回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)
【讨论】:
几乎在那里但不完全 :) 无论如何谢谢 :) 当我运行您提供的功能时,您提供的所有 QHboxLayouts 都被归类为垫片。由于这不是真的“根据该位置的项目返回 QLayoutItem、QWidgetItem 或 QSpacerItem。” => 我的 itemAt 返回不是 QLayoutItem 的 QHboxLayout 我将其修复如下: def clearLayout(self, layout): for i in range(layout.count()): if (type(layout.itemAt(i)) == QtGui. QHBoxLayout): 打印 "layout" + str(layout.itemAt(i)) self.clearLayout(layout.itemAt(i)) else: print "widget" + str(layout.itemAt(i)) if (type(layout. itemAt(i)) == QtGui.QWidgetItem): layout.itemAt(i).widget().close() @user965847:这很奇怪。我得到QLayoutItem
s 的试用版。无论如何,我编辑了代码。试试这个。以上是关于从布局中删除所有项目的主要内容,如果未能解决你的问题,请参考以下文章
删除 ListView 中所有项目的 onClick 突出显示
Qt 5.5 使用 C++,从 ComboBox 中删除和项目正在删除项目之前的所有项目