【问题标题】:QVBoxLayout: How to vertically align widgets to the top instead of the centerQVBoxLayout:如何将小部件垂直对齐到顶部而不是中心
【发布时间】:2012-04-22 08:42:13
【问题描述】:

在 Qt 中,当我将小部件添加到布局时,它们默认垂直居中。有没有办法从上到下“列出”小部件而不是垂直居中?

【问题讨论】:

    标签: qt qlayout


    【解决方案1】:

    使用void QLayout::setAlignment ( Qt::Alignment alignment )方法根据您的选择设置对齐方式。

    【讨论】:

    • 我认为这没有提供足够的信息。首先没有这样的方法:它是(在 PyQt5 中)setAlignment(QWidget *w, Qt::Alignment alignment)setAlignment(QLayout *l, Qt::Alignment alignment),我的第一个实验似乎表明,在 QVBoxLayout 上使用这些方法中的任何一种都不能简单地使其添加的组件成为整齐地与顶部对齐...
    【解决方案2】:

    如果您有 QVBoxLayout 并希望将固定大小的小部件堆叠在顶部,您可以简单地在末尾附加一个垂直拉伸:

    layout.addStretch()
    

    如果您有多个拉伸器或其他拉伸项目,您可以指定一个整数拉伸因子参数来定义它们的大小比例。

    另请参阅addStretchaddSpacerItem

    在添加小部件之前和之后添加两个layout.addStretch() 以使它们垂直居中:

        layout.addStretch()
        layout.addWidget(self.message)
        layout.addWidget(self.userid_field)
        layout.addWidget(self.password_field)
        layout.addWidget(self.loginButton)
        layout.addStretch()
    

    不确定这是否回答了您最初的问题,但它是我在谷歌搜索并被引导到此页面时的答案 - 所以它可能对其他人也有用。

    【讨论】:

    • 有没有办法为帖子添加 500 个赞?
    • 最简单的解决方案。谢谢。
    • 奇怪的 qt 布局很重要
    • 我曾经是这种方法的粉丝,但我刚刚意识到,当顶对齐布局具有顶对齐子布局时,layout.setAlignment(Qt::AlignTop) 提供了比layout.addStretch() 更好的行为。使用 addStretch(),可用空间将在父间隔符和子间隔符之间平均分配:[[h1--][h2--]--]。使用 setAlignment(),空间优先于父级:[[h1][h2]------],将子级的高度保持在其首选高度 h1 和 h2。我认为后者通常是一种更理想的行为,尽管前者可能肯定有用例。
    • @BorisDalstein Strange...我的经验与您所描述的相反。
    【解决方案3】:

    我发现这比使用layout.setAlignment() 稍微复杂一些。直到现在,它一直对我不起作用,当我发现如果您有扩展的小部件并为其设置了最大高度,那么该小部件将不会按照您想要的方式对齐。

    这里是示例代码,即使我调用layout.setAlignment(Qt.AlignTop)顶部对齐QTextBrowser() 小部件。抱歉,它是用 Python 编写的,但它很容易转换为 C++(我已经多次使用另一种方式)。

    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    
    class MyWidget(QWidget):
        """
        Create a widget that aligns its contents to the top.
        """
    
        def __init__(self, parent=None):
    
            QWidget.__init__(self, parent)
    
            layout = QVBoxLayout()
    
            label = QLabel('label:')
            layout.addWidget(label)
    
            info = QTextBrowser(self)
            info.setMinimumHeight(100)
            info.setMaximumHeight(200)
            layout.addWidget(info)        
            # Uncomment the next line to get this to align top.
    #         layout.setAlignment(info, Qt.AlignTop)
    
            # Create a progress bar layout.
            button = QPushButton('Button 1')        
            layout.addWidget(button)        
    
            # This will align all the widgets to the top except
            # for the QTextBrowser() since it has a maximum size set.
            layout.setAlignment(Qt.AlignTop)
    
            self.setLayout(layout)
    
    
    if __name__ == '__main__':
    
        import sys
    
        app = QApplication(sys.argv)
    
        widget = MyWidget()
        widget.show()
        widget.resize(QSize(900, 400))
    
        app.exec_()
    

    以下显式调用layout.setAlignment(info, Qt.AlignTop) 以使扩展文本小部件工作。

    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    
    class MyWidget(QWidget):
        """
        Create a widget that aligns its contents to the top.
        """
    
        def __init__(self, parent=None):
    
            QWidget.__init__(self, parent)
    
            layout = QVBoxLayout()
    
            label = QLabel('label:')
            layout.addWidget(label)
    
            info = QTextBrowser(self)
            info.setMinimumHeight(100)
            info.setMaximumHeight(200)
            layout.addWidget(info)        
            # Uncomment the next line to get this to align top.
            layout.setAlignment(info, Qt.AlignTop)
    
            # Create a progress bar layout.
            button = QPushButton('Button 1')        
            layout.addWidget(button)        
    
            # This will align all the widgets to the top except
            # for the QTextBrowser() since it has a maximum size set.
            layout.setAlignment(Qt.AlignTop)
    
            self.setLayout(layout)
    
    
    if __name__ == '__main__':
    
        import sys
    
        app = QApplication(sys.argv)
    
        widget = MyWidget()
        widget.show()
        widget.resize(QSize(900, 400))
    
        app.exec_()
    

    【讨论】:

    • 这也解决了我的问题。我不太确定为什么需要设置最小宽度/高度。你能解释一下吗?
    【解决方案4】:

    对比两种方案后,似乎是:

    myLayout.setAlignment(Qt.AlignTop)
    

    适用于多个小部件对齐,但:

    myLayout.setAlignment(myWidget, Qt.AlignTop)
    

    仅适用于您添加到布局的第一个小部件。 毕竟,解决方案还取决于您的小部件的 QSizePolicy。

    【讨论】:

    • 这是 PyQt4 的偶然吗?在 PyQt5 中没有 QLayout 方法 setAlignment 与一个参数:只有第二个解决方案存在。
    【解决方案5】:

    如果您使用的是 QT creator,您只需在小部件底部添加一个“垂直间隔”即可。

    【讨论】: