在使用拉伸因子时,多个QHBoxLayout无法对齐
我创建了我自己的自定义QDialog,布局如下(在QGIS中使用Python 3.12.12):
layoutOne = QHBoxLayout()
oneA = QRadioButton("Option 1A")
oneB = QRadioButton("Option 1B")
layoutOne.addWidget(oneA)
layoutOne.addWidget(oneB)
#layoutOne.addStretch(1)
#layoutOne.addSpacing(100)
groupOne = QButtonGroup(self)
groupOne.addButton(oneA)
groupOne.addButton(oneB)
groupOne.setExclusive(True)
layoutTwo = QHBoxLayout()
two = QCheckBox("Checkbox")
layoutTwo.addWidget(two)
two.setChecked(True)
layoutThree = QHBoxLayout()
threeA = QRadioButton("Option 3A")
threeB = QRadioButton("Option 3B")
threeC = QRadioButton("Option 3C")
layoutThree.addWidget(threeA)
layoutThree.addWidget(threeB)
layoutThree.addWidget(threeC)
groupThree = QButtonGroup()
groupThree.addButton(threeA)
groupThree.addButton(threeB)
groupThree.addButton(threeC)
groupThree.setExclusive(True)
self.layout = QVBoxLayout()
self.layout.addLayout(layoutOne)
self.layout.addLayout(layoutTwo)
self.layout.addLayout(layoutThree)
self.setLayout(self.layout)
看起来是这样的:

我想让“Option 1B”与“Option 3B”处于同一列,因此我添加了权重/拉伸:
layoutOne.addWidget(oneA, 1)
layoutOne.addWidget(oneB, 2)

然而,正如你所看到的,出于某种原因它们并没有完全对齐,第二列有2 像素的偏移。
如果再添加一个QHBoxLayout,同样包含两个元素,那么它会与layoutOne完美对齐,但第二个元素也会偏移到layoutThree。
使用layoutOne.addStretch(1)来替代权重几乎移除了所有间距(oneB直接在oneA的右侧),且我不想使用像layoutOne.addSpacing(100)这样的固定像素宽度的东西,因为我希望对话框根据字体大小(即用户的设置)自行设定宽度(和高度)。
导致这个偏移的原因是什么,我该如何让它正确对齐(我不想使用QGridLayout!
解决方案
你可以尝试添加一个空元素——比如QLabel("")或QWidgets()——布局会把这一行当作有三个元素。它会像第三行的项一样重新调整它们的大小。
oneA = QRadioButton("Option 1A")
oneB = QRadioButton("Option 1B")
# oneC = QLabel("")
oneC = QWidget()
layoutOne.addWidget(oneA)
layoutOne.addWidget(oneB)
layoutOne.addWidget(oneC)
我也用 QSpacerItem() 进行了测试,但它需要参数(所以代码会长一些),效果类似于.addStretch(1)——Spacer会占用所有空余空间,在你调整窗口大小时仍会让所有控件左对齐。
但我看到一个问题:如果在单选按钮中使用不同长度的描述,那么元素就不会在同一列。为此需要使用QGridLayout。
我把你的部分代码拿来,借助ChatGPT将其转换为完整程序进行测试
import sys
from PyQt6.QtWidgets import (
QApplication,
QWidget,
QVBoxLayout,
QHBoxLayout,
QSpacerItem,
QLabel,
QRadioButton,
QCheckBox,
QButtonGroup,
)
# from PyQt6.QtWidgets import QSpacerItem, QSizePolicy
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Radio & Checkbox Example")
# --- Layout One ---
layoutOne = QHBoxLayout()
oneA = QRadioButton("Option 1A")
# oneA = QRadioButton("Option 1A with long text")
oneB = QRadioButton("Option 1B")
# oneC = QLabel("")
oneC = QWidget()
# oneC = QSpacerItem(
# 0, 0, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum
# )
layoutOne.addWidget(oneA)
layoutOne.addWidget(oneB)
layoutOne.addWidget(oneC) # for QWidget, QLabel
# layoutOne.addItem(oneC) # for QSpacerItem
# layoutOne.addStretch(1)
# layoutOne.addSpacing(100)
groupOne = QButtonGroup(self)
groupOne.addButton(oneA)
groupOne.addButton(oneB)
groupOne.setExclusive(True)
# --- Layout Two ---
layoutTwo = QHBoxLayout()
two = QCheckBox("Checkbox")
two.setChecked(True)
layoutTwo.addWidget(two)
# --- Layout Three ---
layoutThree = QHBoxLayout()
threeA = QRadioButton("Option 3A")
threeB = QRadioButton("Option 3B")
threeC = QRadioButton("Option 3C")
layoutThree.addWidget(threeA)
layoutThree.addWidget(threeB)
layoutThree.addWidget(threeC)
# layoutThree.addStretch(1)
groupThree = QButtonGroup(self)
groupThree.addButton(threeA)
groupThree.addButton(threeB)
groupThree.addButton(threeC)
groupThree.setExclusive(True)
# --- Main Layout ---
mainLayout = QVBoxLayout()
mainLayout.addLayout(layoutOne)
mainLayout.addLayout(layoutTwo)
mainLayout.addLayout(layoutThree)
self.setLayout(mainLayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。