Как выровнять виджеты в PyQt5 - PullRequest
0 голосов
/ 05 августа 2020

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

enter image description here

But, My code is working something like this,

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

Ниже мой код, может ли кто-нибудь мне помочь?

from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import QRect
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QDesktopWidget, QLabel


class GroupBox(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(QtCore.QRect(20, 20, 900, 700))
        self.setWindowTitle("InvoiceMee - Split Documents")
        layout = QtWidgets.QGridLayout(self)
        groupbox = QtWidgets.QGroupBox("Files to Convert", checkable=False)
        layout.addWidget(groupbox)

        hbox = QtWidgets.QHBoxLayout()
        groupbox.setLayout(hbox)
        label = QLabel()
        pixmap = QPixmap('images.jpg')
        label.setPixmap(pixmap)
        label.resize(pixmap.width(), pixmap.height())
        pathBox = QtWidgets.QLineEdit(self)
        pathBox.setPlaceholderText("Enter the Path Here")
        pathBox.setGeometry(QRect(160, 150, 201, 20))
        selectFileBtn = QtWidgets.QPushButton("Select")
        convertButton = QtWidgets.QPushButton("Convert")
        good_radiobutton = QtWidgets.QRadioButton("Invoices")
        naive_radiobutton = QtWidgets.QRadioButton("Credit Notes")
        hbox.addWidget(pathBox, alignment=QtCore.Qt.AlignCenter)
        hbox.addWidget(selectFileBtn, alignment=QtCore.Qt.AlignCenter)
        hbox.addWidget(convertButton, alignment=QtCore.Qt.AlignCenter)
        hbox.addWidget(good_radiobutton, alignment=QtCore.Qt.AlignCenter)
        hbox.addWidget(naive_radiobutton, alignment=QtCore.Qt.AlignCenter)
        hbox.addWidget(label,alignment=QtCore.Qt.AlignCenter)
        hbox.addStretch()
        self.center()


    def center(self):
        # geometry of the main window
        qr = self.frameGeometry()
        # center point of screen
        cp = QDesktopWidget().availableGeometry().center()
        # move rectangle's center point to screen's center point
        qr.moveCenter(cp)
        # top left of rectangle becomes top left of window centering it
        self.move(qr.topLeft())

Ответы [ 2 ]

1 голос
/ 05 августа 2020

Вы используете QHBoxLayout (что означает горизонтальный макет окна). Это означает, что все добавленные вами виджеты всегда будут отображаться бок о бок по горизонтали в соответствии с порядком вставки .

Вместо этого следует использовать макет, допускающий вертикальную ориентацию.

Вы используете более одного виджета на строку, поэтому вы можете использовать QGridLayout, но, поскольку некоторые из этих виджетов имеют разные горизонтальные размеры, результат может отличаться от того, что вы нам показали. Решение состоит в использовании вложенных макетов с основным макетом сетки с наборами растяжек для первой / третьей строки и столбца и «центральным» макетом, добавленным ко второй строке / столбцу сетки. Затем, когда вам нужно более одного виджета подряд, добавьте вложенный QHBoxLayout.

class GroupBox(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.setGeometry(QtCore.QRect(20, 20, 900, 700))
        self.setWindowTitle("InvoiceMee - Split Documents")
        layout = QtWidgets.QGridLayout(self)
        groupbox = QtWidgets.QGroupBox("Files to Convert", checkable=False)
        layout.addWidget(groupbox)

        # the "main" layout, used to ensure that the actual layout containing
        # all widgets stays in the center
        groupLayout = QtWidgets.QGridLayout()
        groupbox.setLayout(groupLayout)
        groupLayout.setColumnStretch(0, 1)
        groupLayout.setColumnStretch(2, 1)
        groupLayout.setRowStretch(0, 1)
        groupLayout.setRowStretch(2, 1)

        # this is the actual layout used to add widgets
        centerLayout = QtWidgets.QVBoxLayout()
        groupLayout.addLayout(centerLayout, 1, 1)

        label = QLabel()
        pixmap = QPixmap('images.jpg')
        label.setPixmap(pixmap)
        # this won't work
        # label.resize(pixmap.width(), pixmap.height())
        pathBox = QtWidgets.QLineEdit(self)
        pathBox.setPlaceholderText("Enter the Path Here")
        # this won't work either, the layout will try to move and resize it anyway
        # pathBox.setGeometry(QRect(160, 150, 201, 20))
        # use minimum width instead
        pathBox.setMinimumWidth(200)
        selectFileBtn = QtWidgets.QPushButton("Select")
        convertButton = QtWidgets.QPushButton("Convert")
        good_radiobutton = QtWidgets.QRadioButton("Invoices")
        naive_radiobutton = QtWidgets.QRadioButton("Credit Notes")

        centerLayout.addWidget(label, alignment=QtCore.Qt.AlignCenter)

        # the second row has more than one widget, use a nested horizontal layout
        inputLayout = QtWidgets.QHBoxLayout()
        centerLayout.addLayout(inputLayout)
        inputLayout.addWidget(pathBox)
        inputLayout.addWidget(selectFileBtn)

        # the same for the radio buttons
        radioLayout = QtWidgets.QHBoxLayout()
        centerLayout.addLayout(radioLayout)
        # use horizontal alignment to keep buttons closer, otherwise the layout
        # will try to expand them as much as possible (depending on the other
        # widgets in the centerLayout)
        radioLayout.addWidget(good_radiobutton, alignment=QtCore.Qt.AlignRight)
        radioLayout.addWidget(naive_radiobutton, alignment=QtCore.Qt.AlignLeft)

        # use center alignment so that the button doesn't expand
        centerLayout.addWidget(convertButton, alignment=QtCore.Qt.AlignCenter)

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

Кроме того, учтите, что в некоторых случаях может потребоваться установить определенную политику размера c, чтобы виджеты не расширялись слишком сильно, и использование «контейнера» QWidget может сделать все проще. Например, вместо использования горизонтального выравнивания при добавлении переключателей вы можете использовать контейнер QWidget:

        # ...
        radioContainer = QtWidgets.QWidget()
        centerLayout.addWidget(radioContainer, alignment=QtCore.Qt.AlignCenter)
        radioContainer.setSizePolicy(QtWidgets.QSizePolicy.Maximum,
            QtWidgets.QSizePolicy.Preferred)
        radioLayout = QtWidgets.QHBoxLayout(radioContainer)
        radioLayout.addWidget(good_radiobutton)
        radioLayout.addWidget(naive_radiobutton)
        # ...
1 голос
/ 05 августа 2020

Используйте QGridLayout вместо QHBoxLayout. Grid Layout дает вам возможность размещать ваши виджеты в виде сетки, такой как struture. Вот официальная документация для QGridLayout.

Вы можете изменить макет следующим образом:

grid = QtWidgets.QGridLayout()
groupbox.setLayout(grid)
grid.addWidget(label,0,0,1,0,QtCore.Qt.AlignCenter)
grid.addWidget(pathBox,1,0,QtCore.Qt.AlignRight)
grid.addWidget(selectFileBtn,1,1,QtCore.Qt.AlignLeft)
grid.addWidget(good_radiobutton,2,0,QtCore.Qt.AlignRight)
grid.addWidget(naive_radiobutton,2,1,QtCore.Qt.AlignLeft)
grid.addWidget(convertButton,3,0,1,0,QtCore.Qt.AlignCenter)

Добавьте вертикальный разделитель, если вы хотите удалить пространство между ваши виджеты:

verticalSpacer = QtWidgets.QSpacerItem(40, 20,  QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
grid.addItem(verticalSpacer, 6, 0, QtCore.Qt.AlignTop)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...