PyQt5:具有相等列宽的布局按钮

PyQt5 : layout buttons with equal column width

我使用 PyQt5 为我的用户名、密码标签和输入字段以及我的提交和取消按钮创建了一个网格布局。

我为我的所有小部件添加了相等的行宽 1,但是对于我的取消和提交按钮,我希望它们具有相同的单元格宽度。

这是我试过的

from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg
import sys

class MainWindow(qtw.QWidget):
    
    def __init__(self, *arg, **kwargs):
        super().__init__(*arg, **kwargs)
        # custom code goes here
        username_label = qtw.QLabel('Username')
        password_label = qtw.QLabel('Password')

        username_input = qtw.QLineEdit()
        password_input = qtw.QLineEdit(echoMode = qtw.QLineEdit.Password)

        cancel_button = qtw.QPushButton('Cancel')
        submit_button = qtw.QPushButton('Login')
        
        layout = qtw.QGridLayout()
        layout.addWidget(username_label,0, 0, 1, 2) # 0,0 cell, rowspan : 1, colSpan : 2
        layout.addWidget(username_input, 0, 1, 1, 3) # 0, 1 cell
        layout.addWidget(password_label, 1, 0, 1, 2) # 1, 0 cell
        layout.addWidget(password_input, 1, 1, 1, 3) # 1, 1 cell
        layout.addWidget(cancel_button, 2, 0, 1)
        layout.addWidget(submit_button, 2, 1, 1)

        self.setLayout(layout)
        self.show()

if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    w = MainWindow()
    sys.exit(app.exec_())

然而这给了我

如我所料,取消和登录的宽度相等。

修改添加按钮的行:

layout.addWidget(cancel_button, 2, 0, 1, 1)
layout.addWidget(submit_button, 2, 1, 1, 1)

将它们设置到适当的位置:

我的环境:

  • KDE 等离子
  • Python 3.8.2
  • PyQt5 5.15.1

您需要为按钮创建单独的布局,以便它们可以独立于其他小部件调整大小。此外,可以通过使用默认的 row/column 跨度来解决重叠小部件的问题。我还添加了一个可拉伸的垫片,以便在调整 window.

大小时按钮保持在底部
    cancel_button = qtw.QPushButton('Cancel')
    submit_button = qtw.QPushButton('Login')

    hbox = qtw.QHBoxLayout()
    hbox.addWidget(cancel_button)
    hbox.addWidget(submit_button)

    layout = qtw.QGridLayout()
    layout.addWidget(username_label,0, 0)
    layout.addWidget(username_input, 0, 1)
    layout.addWidget(password_label, 1, 0)
    layout.addWidget(password_input, 1, 1)
    layout.setRowStretch(2, 1)
    layout.addLayout(hbox, 3, 0, 1, 2)

    self.setLayout(layout)

默认:

调整大小:

首先,您使用的列跨度参数是错误的:跨度表示小部件将从指定的行或列开始扩展多少个单元格。

如果将标签添加到跨度为 2 的第 0 列,并将行编辑添加到跨度为 3 的第 1 列,结果将是标签将占据前两列,而行编辑将占据第二列第四,结果行编辑将与标签重叠。由于您的布局不需要任何跨度,因此您完全可以避免两个跨度参数。

如果你想要底部按钮占据一半的宽度,不管上面的小部件的大小,那么你需要使用 nested 水平布局:

        layout = qtw.QGridLayout()
        layout.addWidget(username_label,0, 0)
        layout.addWidget(username_input, 0, 1)
        layout.addWidget(password_label, 1, 0)
        layout.addWidget(password_input, 1, 1)
        buttonLayout = qtw.QHBoxLayout()
        layout.addLayout(buttonLayout, 2, 0, 1, 2)
        buttonLayout.addWidget(cancel_button)
        buttonLayout.addWidget(submit_button)

理论上,按钮应该自动展开,但这可能取决于当前的 OS/style 提示,因此您最终可以通过设置 Expanding 大小策略来“强制”它们:

        cancel_button.setSizePolicy(qtw.QSizePolicy.Expanding, 
            qtw.QSizePolicy.Fixed)
        submit_button.setSizePolicy(qtw.QSizePolicy.Expanding, 
            qtw.QSizePolicy.Fixed)