如何调整QLabel的大小以适应QScrollArea中的内容

时间:2018-04-15 05:36:03

标签: python layout pyqt pyqt5 qscrollarea

此问题特定于PyQt5,但C ++ Qt5的答案也很好。

在具有固定宽度和可变高度的QScrollArea中,我有一个QVBoxLayout,其中包含QLabel个。这些QLabels包含setWordWrap(True)并且包含的​​文字可能比QScrollArea的固定宽度更长。当QLabel内的文字换行~~ 4行时,一切正常,但当QLabel需要更多时,它无法继续增加QLabel的高度,并且切割关闭顶部和底部的一些文字。

This answer尝试解决基本相同的问题,包括将QLabel的垂直sizePolicy()设置为MinimumExpanding,此技术上如果视口尚未填充QLabels,则会强制QScrollArea尝试填充整个QLabel视口。

以下是sizePolicy未设置为MinimumExpanding时的当前状态(注意第一个QLabel):

sizePolicy not set

以下是将MinimumExpanding设置为QLabel s的垂直尺寸政策时的外观(看起来很棒......):

sizePolicy set

但是当滚动区域中只有少量QLabel s时会导致此行为,这是不可接受的行为,因为这将是一个“评论”服务,人们可以在其中发布他们的问题纯文本:

unacceptable behavior

是否有人针对此问题制定了解决方法,或者遇到类似的问题?

供参考,以下是我的一些代码:

class NewsList(QtWidgets.QScrollArea):
    def __init__(self, parent=None):
        super(NewsList, self).__init__(parent)
        self.setMaximumWidth(200)
        self.setWidgetResizable(True)

        layout = QtWidgets.QVBoxLayout()
        layout.setContentsMargins(5, 5, 5, 5)
        layout.setSpacing(5)
        layout.setAlignment(QtCore.Qt.AlignTop)
        self.news_widget = QtWidgets.QFrame()
        self.news_widget.setStyleSheet("""
            QFrame {
                background-color: #ffffff;
            }
        """)
        self.news_widget.setLayout(layout)
        self.setWidget(self.news_widget)
        self.fetch_news()

    def fetch_news(self):
        self.append_message('DSADAISH dshadbsasdsadh sd ashd sah dsha dhsa dsa d')
        self.append_message('DSADAISH dshadbsasdsadh sd ashd sah dsha dhsa dsa d')
        self.append_message('DSADAISH dshadbsasdsadh sd ashd sah dsha dhsa dsa d DSADAISH dshadbsasdsadh sd ashd sah dsha dhsa dsa d')
        self.append_message('DSADAISH ')
        self.append_message('DSADAISH ')
        self.append_message('DSADAISH dshadbsasdsadh sd ashd sah dsha dhsa dsa d')
        self.append_message('DSADAISH dshadbsasdsadh sd ashd sah dsha dhsa dsa d')

    def append_message(self, text):
        new_item = QtWidgets.QLabel(text)
        new_item.setWordWrap(True)
        new_item.setStyleSheet("""
            QLabel {
                padding: 4px;
                border: 1px solid black;
                background-color: #ffffff;
            }
        """)

1 个答案:

答案 0 :(得分:2)

使用包含新闻项的布局的addStretch方法可以非常简单地解决这个问题:

class NewsList(QtWidgets.QScrollArea):
    def __init__(self, parent=None):
        ...    
        layout = QtWidgets.QVBoxLayout()
        layout.setContentsMargins(5, 5, 5, 5)
        layout.setSpacing(5)
        layout.setAlignment(QtCore.Qt.AlignTop)
        # add a stretchable space to the bottom of the layout
        layout.addStretch(1)

    def append_message(self, text):
        ...
        # set the size policy of the label
        new_item.setSizePolicy(
            QtWidgets.QSizePolicy.Preferred,
            QtWidgets.QSizePolicy.MinimumExpanding)
        # insert the label before the spacer        
        layout = self.news_widget.layout()
        layout.insertWidget(layout.count() - 1, new_item)

垫片向上推动标签,这会阻止它们拉伸以占用可用空间。使用addStretch stretch-factor 参数可确保spacer始终优先于布局中的其他项。