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

Я учусь делать приложения на Python3 с помощью модуля PyQt5. Решил, что будет здорово хранить виджеты внутри контейнеров - QHBoxLayout и QVBoxLayout(других я не знаю).

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

Тогда подумал, что можно добавлять контейнеры с виджетами в один общий контейнер.

Пожалуйста, подскажите, как правильно сделать то, что я описал?

Нарисовал картинку, чтобы было лучше понятно о чем говорю:

введите сюда описание изображения

Я пытался добиться такого результата двумя способами, но оба привели к ошибкам.

1 способ:

from PyQt5 import QtWidgets
import sys

app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()

button1 = QtWidgets.QPushButton("Кнопка1")
button2 = QtWidgets.QPushButton("Кнопка2")
button3 = QtWidgets.QPushButton("Кнопка3")
button4 = QtWidgets.QPushButton("Кнопка4")

box1 = QtWidgets.QHBoxLayout()
box2 = QtWidgets.QVBoxLayout()
box3 = QtWidgets.QVBoxLayout()

box2.addWidget(button1)
box2.addWidget(button2)

box3.addWidget(button3)
box3.addWidget(button4)

box1.setLayout(box2)
box1.setLayout(box3)
window.setLayout(box1)

window.show()
sys.exit(app.exec_())

Ошибка:

AttributeError: 'QHBoxLayout' object has no attribute 'setLayout'

2 способ:

from PyQt5 import QtWidgets
import sys

app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()

button1 = QtWidgets.QPushButton("Кнопка1")
button2 = QtWidgets.QPushButton("Кнопка2")
button3 = QtWidgets.QPushButton("Кнопка3")
button4 = QtWidgets.QPushButton("Кнопка4")

box1 = QtWidgets.QHBoxLayout()
box2 = QtWidgets.QVBoxLayout()
box3 = QtWidgets.QVBoxLayout()

box2.addWidget(button1)
box2.addWidget(button2)

box3.addWidget(button3)
box3.addWidget(button4)

box1.addWidget(box2)
box1.addWidget(box3)
window.setLayout(box1)

window.show()
sys.exit(app.exec_())

Ошибка:

TypeError: addWidget(self, QWidget, stretch: int = 0, alignment: Union[Qt.Alignment, Qt.AlignmentFlag] = Qt.Alignment()): argument 1 has unexpected type 'QVBoxLayout'


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

Автор решения: Эникейщик

Правильно сделать используя QGridLayout, который как раз позволяет делать табличную разметку.

Пример.

введите сюда описание изображения

→ Ссылка
Автор решения: S. Nick

Вам надо было сделать еще одну попытку.

QBoxLayout::addLayout(QLayout *layout, int stretch = 0)

Добавляет layout в конец box с коэффициентом растяжения.

Но во многих случаях вам очень пригодится QGridLayout и QFormLayout

from PyQt5 import QtWidgets
import sys

app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()

button1 = QtWidgets.QPushButton("Кнопка1")
button2 = QtWidgets.QPushButton("Кнопка2")
button3 = QtWidgets.QPushButton("Кнопка3")
button4 = QtWidgets.QPushButton("Кнопка4")

box1 = QtWidgets.QHBoxLayout()
box2 = QtWidgets.QVBoxLayout()
box3 = QtWidgets.QVBoxLayout()

box2.addWidget(button1)
box2.addWidget(button2)

box3.addWidget(button3)
box3.addWidget(button4)

#box1.setLayout(box2)
box1.addLayout(box2)            # <<<
box1.addLayout(box3)            # <<<
window.setLayout(box1)

window.show()
sys.exit(app.exec_())

введите сюда описание изображения

→ Ссылка