【问题标题】:Set minimal reasonable width for a QScrollArea为 QScrollArea 设置最小合理宽度
【发布时间】:2017-11-14 10:10:57
【问题描述】:

我对 Qt 比较陌生,我通过 PySide 访问它。

我想要垂直滚动的内容列表很长。 水平尺寸不是问题。为此,我尝试使用QScrollArea。这是一个最小的例子:

import sys

import PySide.QtGui as gui

application = gui.QApplication(sys.argv)

window = gui.QScrollArea()
list = gui.QWidget()
layout = gui.QVBoxLayout(list)

for i in range(100):
    layout.addWidget(gui.QLabel(
        "A something longish, slightly convoluted example text."))

window.setWidget(list)

window.show()

sys.exit(application.exec_())

会发生什么:

  1. 滚动区域将其水平大小设置为标签所需的大小

  2. 注意到垂直空间不足,添加了垂直滚动条。

  3. 由于垂直滚动条,现在水平空间也不够了,所以水平滚动条也显示出来了。

我可以使用setHorizontalScrollBarPolicy 使水平滚动条消失,但主要问题仍然存在:垂直滚动条会遮挡部分标签。

如何将滚动区域的宽度设置为不需要水平滚动条的最小值?

【问题讨论】:

    标签: python qt pyside qscrollarea


    【解决方案1】:

    您的示例有些不切实际,因为滚动区域是顶级窗口。更典型的是,它是一个子小部件,其初始大小将由布局确定,并且会间接受到其他小部件和/或布局的大小的约束。作为顶级窗口,约束是不同的,并且部分受窗口管理器的影响(其确切行为可能因平台而异)。

    为确保滚动区域的大小正确,您必须根据其内容为其设置最小宽度,并允许垂直滚动条和框架。最好将widgetResizable 属性设置为True 并在内容布局的末尾添加一个可扩展的分隔符。

    在下面的示例中,我更改了标签的背景颜色,以便更容易看到正在发生的事情。我还允许通过在显示后重置最小宽度来调整窗口小于其初始大小的大小 - 但这是可选的。

    import sys
    
    import PySide.QtGui as gui
    
    application = gui.QApplication(sys.argv)
    
    window = gui.QScrollArea()
    window.setWidgetResizable(True)
    list = gui.QWidget()
    layout = gui.QVBoxLayout(list)
    
    # just for testing
    window.setStyleSheet('QLabel {background-color: red}')
    
    for i in range(30):
        layout.addWidget(gui.QLabel(
            "A something longish, slightly convoluted example text."))
    
    layout.addStretch()
    
    window.setWidget(list)
    
    window.setMinimumWidth(
        list.sizeHint().width() +
        2 * window.frameWidth() +
        window.verticalScrollBar().sizeHint().width())
    
    window.show()
    
    # allow resizing smaller
    window.setMinimumWidth(1)
    
    sys.exit(application.exec_())
    

    【讨论】:

    • 是的,作为主窗口的 QScrollArea 是示例最小化的一部分。在实际应用程序中,它位于 QStackedWidget 内。
    • @kne。无论哪种方式,我的答案都是正确的解决方案。你真的试过了吗?
    • 它工作正常,谢谢。我只是不明白为什么。 IIUC,list.layout().getContentsMargins()[2] 等价于layout.contentsMargins().right()。左边距如何?从视觉上看,所有四个方向都有边距。左边距是否已经包含在window.verticalScrollBar().sizeHint().width() 中?
    • @kne。是的,我犯了一个愚蠢的错误,因为布局内容的边距恰好是滚动区域框架宽度的两倍。我已经更正了我的答案,所以希望它现在完全有意义。
    • 再次感谢您。我没有意识到 QWidget 和 QAbstractScrollArea 之间有一个中间类(在这种情况下为 QFrame)。 PySide 文档并不能完全轻松地识别祖先(以及完整的方法列表)。你的修正让我大开眼界!
    【解决方案2】:

    尝试在小部件中使用 sizeHint() 并使用结果设置 QScrollArea 的最小宽度。

    这里有一些额外的信息:http://doc.qt.io/qt-5/layout.html

    【讨论】:

    • 如果我没记错的话,这不包括垂直滚动条、框架和边距所需的空间。
    • 你是对的。不考虑垂直滚动条的空间。我忘了在我之前的评论中添加这个。
    猜你喜欢
    • 2012-04-05
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多