Удалить виджеты и макет, а также
Я пытался найти что-то, что бы взять макет qt и удалить из него все. Просто чтобы представить, как выглядит окно - у меня есть:
QVBoxLayout
| ------QHboxLayout
|---------QWidget
| ------QHboxLayout
|---------QWidget
.........
Поэтому мне нужно что-то, что я могу вызвать рекурсивно, чтобы очистить и удалить все вещи от моего родителя QVBoxLayout
, Я попробовал вещи, упомянутые здесь ( Очистить все виджеты в макете в 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()
2 ответа
Самый безопасный способ очистить макет - извлечь элементы с помощью метода 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())
Проблема с вашим кодом 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)