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

Posted

技术标签:

【中文标题】PyQt5:具有相等列宽的布局按钮【英文标题】:PyQt5 : layout buttons with equal column width 【发布时间】:2022-01-07 10:09:36 【问题描述】:

我正在使用 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_())

但是这给了我

如我所料,取消并登录以具有相等的宽度。

【问题讨论】:

【参考方案1】:

修改添加按钮的行:

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

【讨论】:

我希望取消和登录在整个窗口列大小上具有相等的宽度,即一半和一半【参考方案2】:

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

    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)

默认值:

调整大小:

【讨论】:

【参考方案3】:

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

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

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

        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)

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

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

【讨论】:

以上是关于PyQt5:具有相等列宽的布局按钮的主要内容,如果未能解决你的问题,请参考以下文章

float clear

基础固定列宽的表格及示例演示

Flutter 布局 3 列宽 3 行深,图标和文本在下方 - 图标 OnPressed(不是导航栏,而是全屏)

如何制作具有固定列宽的 chrome 尊重表

如何在 Python 中打印具有指定列宽的列表?

多列布局——column-width