Как сделать положение виджетов динамическим в PyQt5?

Как сделать, чтобы при увеличении или уменьшении окна виджеты соответственно меняли своё расположение/размеры (желательно еще и в определенных пределах).

Чем можно воспользоваться для достижения такого результата?

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

Допустим, есть такой вот код:

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout

import sys


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

        self.initUI()

    def initUI(self):
        self.setGeometry(300, 100, 975, 795)
        self.setStyleSheet("background-color: #24232d;")


        self.scrollArea = QtWidgets.QScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollArea.setStyleSheet("border: 2px solid #fff;")
        self.scrollArea.setMaximumSize(970, 400)
        self.scrollArea.setMinimumSize(485, 200)

        self.choose_btn = QtWidgets.QPushButton()
        self.choose_btn.setGeometry(QtCore.QRect(30, 480, 141, 31))
        font = QtGui.QFont()
        font.setFamily("Bahnschrift SemiBold SemiConden")
        font.setPointSize(10)
        font.setBold(True)
        font.setItalic(False)
        font.setWeight(75)
        self.choose_btn.setFont(font)
        self.choose_btn.setStyleSheet("QPushButton {\n"
                                      "    border: 1px solid #fff;\n"
                                      "    color: #fff;\n"
                                      "}")
        self.choose_btn.setObjectName("pushButton")

        self.comboBox = QtWidgets.QComboBox()
        self.comboBox.setGeometry(QtCore.QRect(190, 480, 61, 31))
        self.comboBox.setStyleSheet("background-color: #fff;")
        self.comboBox.setObjectName("comboBox")

        self.open_btn = QtWidgets.QPushButton()
        self.open_btn.setGeometry(QtCore.QRect(800, 480, 141, 31))
        font = QtGui.QFont()
        font.setFamily("Bahnschrift SemiBold SemiConden")
        font.setPointSize(10)
        font.setBold(True)
        font.setItalic(False)
        font.setWeight(75)
        self.open_btn.setFont(font)
        self.open_btn.setStyleSheet("QPushButton {\n"
                                    "    border: 1px solid #fff;\n"
                                    "    color: #fff;\n"
                                    "}")
        self.open_btn.setObjectName("pushButton_2")

        self.hbox1 = QHBoxLayout()
        self.hbox1.addWidget(self.scrollArea, Qt.AlignTop | Qt.AlignCenter)
        self.hbox1.addStretch(0)

        self.hbox2 = QHBoxLayout()
        self.hbox2.addWidget(self.open_btn)
        self.hbox2.addWidget(self.choose_btn)
        self.hbox2.addWidget(self.comboBox)

        self.vbox = QVBoxLayout()
        self.vbox.addSpacing(50)
        self.vbox.addLayout(self.hbox1, 1)
        self.vbox.addLayout(self.hbox2, 2)

        self.setLayout(self.vbox)


if __name__ == '__main__':

    app = QtWidgets.QApplication([])
    app.setStyle('Fusion')
    application = MainWindow()
    application.show()

    sys.exit(app.exec_())

Что нужно добавить для того, чтобы scrollArea не прилипала к левой стороне и находилась всегда сверху, а также изменяла свои размеры пропорционально (в дальнейшем просто планирую размещать там большое изображение); между кнопками появилось пространство и они стали меньше?

Конечный вариант того, что я хотел бы видеть:

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


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

Автор решения: S. Nick

Попробуйте так:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, \
    QGridLayout, QWidget


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

    def initUI(self):
#        self.setGeometry(300, 100, 975, 795)
        self.resize(975, 500)
        self.setStyleSheet("background-color: #24232d;")

        self.scrollArea = QtWidgets.QScrollArea()
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollArea.setStyleSheet("border: 2px solid #fff;")
        self.scrollArea.setMaximumSize(970, 400)
        self.scrollArea.setMinimumSize(485, 200)
        self.scrollArea.setStyleSheet("background-color: #24237d;")

        self.choose_btn = QtWidgets.QPushButton('choose_btn')
#        self.choose_btn.setGeometry(QtCore.QRect(30, 480, 141, 31))
        font = QtGui.QFont()
        font.setFamily("Bahnschrift SemiBold SemiConden")
        font.setPointSize(10)
        font.setBold(True)
        font.setItalic(False)
        font.setWeight(75)
        self.choose_btn.setFont(font)
        self.choose_btn.setStyleSheet("""
            QPushButton {
                border: 1px solid #fff;
                color: #fff;
            }
        """)
        self.choose_btn.setObjectName("pushButton")

        self.comboBox = QtWidgets.QComboBox()
#        self.comboBox.setGeometry(QtCore.QRect(190, 480, 61, 31))
        self.comboBox.setStyleSheet("background-color: #fff;")
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem('comboBox:') 

        self.open_btn = QtWidgets.QPushButton('open_btn')
#        self.open_btn.setGeometry(QtCore.QRect(800, 480, 141, 31))
        font = QtGui.QFont()
        font.setFamily("Bahnschrift SemiBold SemiConden")
        font.setPointSize(10)
        font.setBold(True)
        font.setItalic(False)
        font.setWeight(75)
        self.open_btn.setFont(font)
        self.open_btn.setStyleSheet("QPushButton {\n"
                                    "    border: 1px solid #fff;\n"
                                    "    color: #fff;\n"
                                    "}")
        self.open_btn.setObjectName("pushButton_2")

# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv 
        self.widget = QWidget()                                      # +++ self.widget
        self.widget.setMaximumWidth(970)                             # +++
        self.hbox2 = QHBoxLayout(self.widget)                        # +++ self.widget
        self.hbox2.setContentsMargins(0, 5, 0, 0)                    # +++
        self.hbox2.addWidget(self.open_btn)
        self.hbox2.addWidget(self.choose_btn)
        self.hbox2.addStretch()                                      # +++
        self.hbox2.addWidget(self.comboBox)

        self.layout = QGridLayout(self)                              # +++ QGridLayout
        self.layout.addWidget(self.scrollArea, 1, 1, 1, 1)
        self.layout.addWidget(self.widget, 2, 1, 1, 1) 
        
        self.layout.setRowStretch(1, 2)
        self.layout.setRowStretch(2, 0)
        self.layout.setRowStretch(3, 1)
        
        self.layout.setColumnStretch(0, 1)
        self.layout.setColumnStretch(1, 100)
        self.layout.setColumnStretch(2, 1)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 


if __name__ == '__main__':

    app = QtWidgets.QApplication([])
    app.setStyle('Fusion')
    application = MainWindow()
    application.show()

    sys.exit(app.exec_())

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

→ Ссылка