Как очистить контейнер PyQt5, который находится в другом контейнере?(Python3)

Вчера уже задавал здесь подобный вопрос и получил очень хороший ответ - мне нужно было очистить контейнер модуля PyQt5, Как обновить контейнер в PyQt5?(Python3). Т.к. я не знал принцип удаления виджетов из контейнера, думал, что иерархия контейнеров в окне не имеет никакого значения. Сейчас же у меня появилась необходимость поместить QGridLayout в QHBoxLayout, а в QGridLayout поместить кнопки, одна из которых будет очищать QGridLayout и добавлять новую кнопку в этот же QGridLayout. При этом я бы хотел сохранить остальные виджеты QHBoxLayout в покое. Чтобы было лучше понятно о чем говорю, нарисовал схему: введите сюда описание изображения

Очень старался сделать картинку максимально понятной, поэтому, если что-то получилось плохо, пожалуйста, сообщите мне, чтобы я мог учесть это в следующий раз.

Пожалуйста, подскажите, есть ли возможность очистить контейнер, который находится внутри другого контейнера? Или здесь уже нужно воспользоваться методами repaint() и update()?

from PyQt5 import QtCore, QtWidgets, QtGui

class MyWindow(QtWidgets.QWidget):

    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)

        self.box1 = QtWidgets.QHBoxLayout()

        self.button1 = QtWidgets.QPushButton('Button1')
        self.button1.clicked.connect(self.click)
        self.button2 = QtWidgets.QPushButton('Button2')
        self.button3 = QtWidgets.QPushButton('Button3')
        self.button4 = QtWidgets.QPushButton('Button4')
        self.button5 = QtWidgets.QPushButton('Button5')

        self.box2 = QtWidgets.QGridLayout()
        self.box2.addWidget(self.button1, 0, 0)
        self.box2.addWidget(self.button2, 0, 1)
        self.box2.addWidget(self.button3, 1, 0)
        self.box2.addWidget(self.button4, 1, 1)

        self.box1.addLayout(self.box2)
        self.box1.addWidget(self.button5)
        self.setLayout(self.box1)

    def click(self):
        count = self.layout().count()
        for i in range(count-1, -1, -1):
            layoutItem = self.layout().itemAt(i)
            w = layoutItem.widget()
            if w:
                self.layout().removeWidget(w)
                w.setParent(None)
                w.deleteLater()

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle(' ')
    window.show()
    sys.exit(app.exec_())

Сейчас этот код работает неправильно, т.к. теперь появился второй контейнер.


Ответы (1 шт):

Автор решения: gil9red

Сделал удаление из QGridLayout и добавление новой кнопки, что занимает все ячейки.

Добавление New Button выполняется через реализацию addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment()), которая позволяет виджету заполнять несколько ячеек, подробнее:

This version adds the given widget to the cell grid, spanning multiple rows/columns. The cell will start at fromRow, fromColumn spanning rowSpan rows and columnSpan columns. The widget will have the given alignment. If rowSpan and/or columnSpan is -1, then the widget will extend to the bottom and/or right edge, respectively.

Пример:

from PyQt5 import QtCore, QtWidgets, QtGui

class MyWindow(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.box1 = QtWidgets.QHBoxLayout()

        self.button1 = QtWidgets.QPushButton('Button1')
        self.button1.clicked.connect(self.click)
        self.button2 = QtWidgets.QPushButton('Button2')
        self.button3 = QtWidgets.QPushButton('Button3')
        self.button4 = QtWidgets.QPushButton('Button4')
        self.button5 = QtWidgets.QPushButton('Button5')
        self.button6 = QtWidgets.QPushButton('New Button')

        self.box2 = QtWidgets.QGridLayout()
        self.box2.addWidget(self.button1, 0, 0)
        self.box2.addWidget(self.button2, 0, 1)
        self.box2.addWidget(self.button3, 1, 0)
        self.box2.addWidget(self.button4, 1, 1)

        self.box1.addLayout(self.box2)
        self.box1.addWidget(self.button5)
        self.setLayout(self.box1)

    def click(self):
        for row in range(self.box2.rowCount()):
            for col in range(self.box2.columnCount()):
                w = self.box2.itemAtPosition(row, col).widget()
                w.deleteLater()

        self.box2.addWidget(self.button6, 0, 0, 1, 1, QtCore.Qt.AlignCenter)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MyWindow()
    window.setWindowTitle(' ')
    window.show()
    sys.exit(app.exec_())
→ Ссылка