Получить виджеты макета в PyQT

У меня есть QVBoxLayout, в который я добавил несколько виджетов через addWidget(). Теперь мне нужно удалить эти виджеты, и, кажется, мне нужно использовать removeWidget() (который принимает удаляемый виджет), чтобы сделать это.

Я думал, что вызов children() или findChildren(QWidget) в моем макете вернет список виджетов, которые я добавил в него; Однако я нахожусь в отладчике и просто получаю пустые списки.

Я что-то ужасно не понимаю? Я только начал заниматься PyQT на прошлой неделе и в основном учился методом проб и ошибок с документами API.


person Xiong Chiamiov    schedule 19.06.2010    source источник


Ответы (2)


Это странно. Насколько я понимаю, добавление виджетов через addWidget передает право собственности на макет, поэтому вызов children() должен работать.

Однако в качестве альтернативы вы можете перебрать элементы макета, используя count() и itemAt(int), чтобы передать QLayoutItem в removeItem(QLayoutItem*).

Изменить:

Я только что попробовал addWidget с прямым тестовым приложением C++. и он не передает право собственности QObject макету, поэтому children() действительно является пустым списком. В документах ясно сказано, что право собственности передается...

Редактировать 2:

Хорошо, похоже, что он передает право собственности виджету с таким макетом (что не указано в документации). Это делает элементы в макете братьями и сестрами самого макета в QObject иерархии! Поэтому проще придерживаться count и itemAt.

person Troubadour    schedule 19.06.2010
comment
Кажется, это помогает, спасибо. Это не работает так, как мне бы хотелось, но, похоже, это связано с некоторыми проблемами обновления дисплея, которые мне нужно сгладить, которые совершенно не зависят от этого. - person Xiong Chiamiov; 20.06.2010
comment
О, так itemAt выдает QWidgetItem (что требует использования removeItem, который по какой-то причине не делал того, что я хотел). Однако если вы вызовете для него .widget(), вы получите (шок!) QWidget, связанный с ним, который можно удалить с помощью removeWidget и установить родителем None. - person Xiong Chiamiov; 20.06.2010

Чтобы получить виджет из QLayout, вы должны вызвать его метод itemAt(index). Как следует из названия этого метода, он возвращает элемент вместо виджета. Вызов widget() для результата, наконец, даст вам виджет:

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

Чтобы удалить виджет, установите для родительского виджета значение None:

myWidget.setParent(None)

Также очень полезен метод QLayout count(). Чтобы найти и удалить все содержимое макета:

index = myLayout.count()
while(index >= 0):
    myWidget = myLayout.itemAt(index).widget()
    myWidget.setParent(None)
    index -=1
person Arnoud Vangrunderbeek    schedule 24.08.2017
comment
index = myLayout.count()-1 Я согласен с этим ответом, но -1 должен быть вверху, так как индекс начинается с 0, и если вы этого не сделаете, индекс дойдет до -1 в цикле. - person abhishek mishra; 16.08.2020