Как настроить величину отступа меежду элементами QGridLayout?

В контейнере box находятся четыре виджета:

  • picture - скругленное изображение, полученное с помощью класса RoundArt;
  • три виджета Qlabel:
    • album_title;
    • artist;
    • year.

Окно приложения:

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

Виджеты Qlabel расползаются по всему контейнеру так, как хотят. Я никак не могу их контролировать и очень хочу это исправить, задав расстояние между виджетами box:

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

L - расстояние по горизонтали от picture до каждого Qlabel'а. Важно сохранить выравнивание текста по левому краю. Должно быть постоянным и равным 10px

H - расстояние по вертикали между виджетами Qlabel. Должно быть постоянным и равным 20px

Пожалуйста, помогите мне расположить виджеты в контейнере box.

from PyQt5 import QtCore, QtWidgets, QtGui

class RoundArt(QtWidgets.QLabel):
    clicked = QtCore.pyqtSignal()

    def __init__(self, picture, x, *args, **kwargs):
        super(RoundArt, self).__init__(*args, **kwargs)

        self.setFixedSize(x, x)
        self.x = x
        self.radius = 10 

        self.setPicture(picture)

    def setPicture(self, picture):
        target = QtGui.QPixmap(self.size())
        target.fill(QtCore.Qt.transparent)

        p = QtGui.QPixmap(picture).scaled(
            self.x, self.x, QtCore.Qt.KeepAspectRatioByExpanding,
            QtCore.Qt.SmoothTransformation
        )

        painter = QtGui.QPainter(target)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        painter.setRenderHint(QtGui.QPainter.HighQualityAntialiasing, True)
        painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform, True)

        path = QtGui.QPainterPath()
        path.addRoundedRect(0, 0, self.width(), self.height(), self.radius, self.radius)
        painter.setClipPath(path)
        painter.drawPixmap(0, 0, p)
        self.setPixmap(target)

        painter.end()
        target = None

    def mouseReleaseEvent(self, event):
        self.clicked.emit()

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

        box = QtWidgets.QGridLayout(self)

        picture = RoundArt('album.png', 150)
        box.addWidget(picture, 0, 0, 3, 1)

        album_title = QtWidgets.QLabel('Album Title')
        box.addWidget(album_title, 0, 1)

        artist = QtWidgets.QLabel('Artist')
        box.addWidget(artist, 1, 1)

        year = QtWidgets.QLabel('2001')
        box.addWidget(year, 2, 1)


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

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

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

Проще воспользоваться комбинацией Layout-ов. Попробуйте так:

from PyQt5 import QtCore, QtWidgets, QtGui

class RoundArt(QtWidgets.QLabel):
    clicked = QtCore.pyqtSignal()

    def __init__(self, picture, x, *args, **kwargs):
        super(RoundArt, self).__init__(*args, **kwargs)
        self.setFixedSize(x, x)
        self.x = x
        self.radius = 10 
        self.setPicture(picture)

    def setPicture(self, picture):
        target = QtGui.QPixmap(self.size())
        target.fill(QtCore.Qt.transparent)
        p = QtGui.QPixmap(picture).scaled(
            self.x, self.x, QtCore.Qt.KeepAspectRatioByExpanding,
            QtCore.Qt.SmoothTransformation
        )
        painter = QtGui.QPainter(target)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        painter.setRenderHint(QtGui.QPainter.HighQualityAntialiasing, True)
        painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform, True)
        path = QtGui.QPainterPath()
        path.addRoundedRect(0, 0, self.width(), self.height(), self.radius, self.radius)
        painter.setClipPath(path)
        painter.drawPixmap(0, 0, p)
        self.setPixmap(target)
        painter.end()
        target = None

    def mouseReleaseEvent(self, event):
        self.clicked.emit()


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

#        box = QtWidgets.QGridLayout(self)
        box = QtWidgets.QHBoxLayout(self)

        picture = RoundArt('head3.png', 150)
        box_V = QtWidgets.QVBoxLayout()
        box_V.addWidget(picture)
        box_V.addStretch(1)
        box.addLayout(box_V)
        box.addSpacing(10)

        box_V = QtWidgets.QVBoxLayout()
        album_title = QtWidgets.QLabel('Album Title')
        album_title.setFixedHeight(30)
#        box.addWidget(album_title, 0, 1)
        box_V.addSpacing(10)
        box_V.addWidget(album_title)
        box_V.addSpacing(20)

        artist = QtWidgets.QLabel('Artist')
        artist.setFixedHeight(30)
#        box.addWidget(artist, 1, 1)
        box_V.addWidget(artist)
        box_V.addSpacing(20)

        year = QtWidgets.QLabel('2001')
        year.setFixedHeight(30)
#        box.addWidget(year, 2, 1)
        box_V.addWidget(year)
        box_V.addSpacing(10)
        box_V.addStretch(1)

        box.addLayout(box_V)


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

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

→ Ссылка