The posted code creates a single window with 5 rows of widgets.
Clicking Push Button
fires up btnClicked
function which fails to clear the window from all the widgets using .takeAt()
method. Why?
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication([])
view = QtGui.QWidget()
view.setLayout(QtGui.QVBoxLayout())
def btnClicked():
items = []
for i in range( view.layout().count() ):
item = view.layout().itemAt(i)
items.append(item)
for num, item in enumerate(items):
print 'taking out item:', num, item
view.layout().takeAt(num)
for i in range(5):
sublayout = QtGui.QHBoxLayout()
view.layout().addLayout(sublayout)
sublayout.addWidget(QtGui.QLabel('Label:'))
sublayout.addWidget(QtGui.QLineEdit('Text Edit'))
btn = QtGui.QPushButton('Push Button')
btn.clicked.connect(btnClicked)
sublayout.addWidget(btn)
view.show()
app.exec_()
Firstly, you can't safely remove items from a container whilst iterating over it. Every time you take an item out of the layout, the remaining items will all move down, and their indexes will change accordingly. As a consequence, once the half-way point has been passed, your loop counter will no longer refer to a valid item. The correct way to remove the items in a loop is like this:
def btnClicked():
layout = view.layout()
while layout.count():
item = layout.takeAt(0)
print(repr(item))
Secondly, the layout items you are removing are layout-items, not widgets. Once all the layouts have been removed, all the widgets will be left where they are. You can see this if you use the method above, and then resize the window - the widgets are no longer managed by any layout, and so they are not also resized.
When widgets are added to a layout, they are automatically re-parented to the widget that owns the layout. If that parent widget is deleted, all its children will be recursively deleted as well. So a widget (or its parent) has to be explicitly deleted in order to for it to be removed completely:
def clearLayout(layout):
if layout is not None:
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.deleteLater()
else:
clearLayout(item.layout())
def btnClicked():
clearLayout(view.layout())