Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a layout's widgets in PyQT

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.

like image 262
Xiong Chiamiov Avatar asked Jun 19 '10 20:06

Xiong Chiamiov


People also ask

What is stacked widget in PyQt5?

QStackedWidget can be used to create a user interface similar to the one provided by QTabWidget . It is a convenience layout widget built on top of the QStackedLayout class. Like QStackedLayout , QStackedWidget can be constructed and populated with a number of child widgets (“pages”):

What is layout in PyQt?

In PyQt, layout managers are classes that provide the required functionality to automatically manage the size, position, and resizing behavior of the widgets in the layout. With layout managers, you can automatically arrange child widgets within any parent, or container, widget.

What are PyQt5 widgets?

Widgets are basic building blocks of an application. PyQt5 has a wide range of various widgets, including buttons, check boxes, sliders, or list boxes.

What is QVBoxLayout?

QVBoxLayout organizes your widgets vertically in a window. Instead of organizing all the widgets yourself (specifying the geographic location), you can let PyQt take care of it. Every new widget you add with . addWidget() , is added vertically. Basically you get a vertical list of your widgets.


2 Answers

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
like image 178
Arnoud Vangrunderbeek Avatar answered Oct 02 '22 14:10

Arnoud Vangrunderbeek


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.

like image 42
Troubadour Avatar answered Oct 02 '22 14:10

Troubadour