21

I have a QVBoxLayout that I've added a few widgets to, via addWidget(). I need to now delete those widgets, and it seems I need to use removeWidget() (which takes in a widget to be removed) to do that.

I thought that calling children() or findChildren(QWidget) on my layout would return a list of the widgets I've added into it; I'm in the debugger, though, and am just receiving empty lists.

Am I terribly misunderstanding something? I've just started doing PyQT this last week and have mostly been learning through trial and error with the API docs.

Xiong Chiamiov
  • 13,076
  • 9
  • 63
  • 101

2 Answers2

27

To get a widget from a QLayout, you have to call its itemAt(index) method. As the name of this method implies, it will return an item instead of a widget. Calling widget() on the result will finally give you the widget:

myWidget = self.myLayout.itemAt(index).widget()

To remove a widget, set the parent widget to None:

myWidget.setParent(None)

Also really helpfull is the QLayout count() method. To find and delete all contents of a layout:

index = myLayout.count()
while(index >= 0):
    myWidget = myLayout.itemAt(index).widget()
    myWidget.setParent(None)
    index -=1
  • 1
    `index = myLayout.count()-1` I agree with this answer but the -1 should be there at the top as index starts from 0 and if you dont do that the index goes till -1 in the loop. – abhishek mishra Aug 16 '20 at 18:16
18

That's odd. My understanding is that adding widgets via addWidget transfers ownership to the layout so calling children() ought to work.

However, as an alternative you could loop over the layout items by using count() and itemAt(int) to supply a QLayoutItem to removeItem(QLayoutItem*).

Edit:

I've just tried addWidget with a straight C++ test app. and it doesn't transfer QObject ownership to the layout so children() is indeed an empty list. The docs clearly say that ownership is transferred though...

Edit 2:

Okay, it looks as though it transfers ownership to the widget that has that layout (which is not what the docs said). That makes the items in the layout siblings of the layout itself in the QObject hierarchy! It's therefore easier to stick with count and itemAt.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Troubadour
  • 13,334
  • 2
  • 38
  • 57
  • That seems to do the trick, thank you. It doesn't work quite as I'd like it, but that appears to be due to some display updating issues I need to iron out, which are quite independent of this. – Xiong Chiamiov Jun 19 '10 at 22:07
  • 1
    Oh, so `itemAt` gives out a QWidgetItem (which necessitates the usage of `removeItem`, which for whatever reason wasn't doing what I wanted). If you call `.widget()` on it, though, you'll get (shock!) the QWidget associated with it, which can be removed with `removeWidget` and set to have a parent of `None`. – Xiong Chiamiov Jun 19 '10 at 23:20