Clear all widgets in a layout in pyqt
Is there a way to clear (delete) all the widgets in a layout?
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())
Now I want to replace the widget in plot_layout
with a new widget. Is there an easy way to clear all the widgets in plot_layout
? I don't see any method such.
After a lot of research (and this one took quite time, so I add it here for future reference), this is the way I found to really clear and delete the widgets in a layout:
for i in reversed(range(layout.count())):
layout.itemAt(i).widget().setParent(None)
What the documentation says about the QWidget is that:
The new widget is deleted when its parent is deleted.
Important note: You need to loop backwards because removing things from the beginning shifts items and changes the order of items in the layout.
To test and confirm that the layout is empty:
for i in range(layout.count()): print i
There seems to be another way to do it. Instead of using the setParent function, use the deleteLater() function like this:
for i in reversed(range(layout.count())):
layout.itemAt(i).widget().deleteLater()
The documentation says that QObject.deleteLater (self)
Schedules this object for deletion.
However, if you run the test code specified above, it prints some values. This indicates that the layout still has items, as opposed to the code with setParent .
This may be a bit too late but just wanted to add this for future reference:
def clearLayout(layout):
while layout.count():
child = layout.takeAt(0)
if child.widget():
child.widget().deleteLater()
Adapted from Qt docs http://doc.qt.io/qt-5/qlayout.html#takeAt. Remember that when you are removing children from the layout in a while or for loop, you are effectively modifying the index # of each child item in the layout. That's why you'll run into problems using a for i in range()
loop.
The answer from PALEN works well if you do not need to put new widgets to your layout.
for i in reversed(range(layout.count())):
layout.itemAt(i).widget().setParent(None)
But you will get a "Segmentation fault (core dumped)" at some point if you empty and fill the layout many times or with many widgets. It seems that the layout keeps a list of widget and that this list is limited in size.
If you remove the widgets that way:
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 )
You won't get that problem.
链接地址: http://www.djcxy.com/p/77400.html上一篇: 定位和显示自定义小部件
下一篇: 在pyqt中清除布局中的所有小部件