[英]How to align widgets in PyQt5
我正在尝试将 PyQt5 用于我的 GUI 应用程序之一。 我可以根据需要添加小部件,但无法正确对齐它们。 我想如下对齐我的小部件:
但是,我的代码是这样工作的,
以下是我的代码,有人可以帮我吗?
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())
使用QGridLayout
而不是QHBoxLayout
。 Grid Layout 让您可以选择在类似结构的网格中布局小部件。 这是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)
您正在使用 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 轻松查看嵌套布局的工作原理。
此外,请考虑在某些情况下可能需要设置特定的大小策略以避免小部件过度扩展,并且使用 QWidget“容器”可以使事情变得更容易。
例如,当您添加单选按钮时,您可以使用 QWidget 容器,而不是使用水平 alignment:
# ...
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)
# ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.