在使用拉伸因子时,多个QHBoxLayout无法对齐

编程语言 2026-07-12

我创建了我自己的自定义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导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章