如何调整 QLabel 的大小以适应 QScrollArea 中的内容
How to resize QLabels to fit contents in QScrollArea
此问题特定于 PyQt5,但 C++ Qt5 答案也很好。
在固定宽度和可变高度的 QScrollArea 中,我有一个包含 QLabel
的 QVBoxLayout
。这些 QLabels
有 setWordWrap(True)
并且包含的文本可能比 QScrollArea
的固定宽度长。当 QLabel
中的文本换行到 ~4 行时,一切正常,但是当 QLabel
需要更多时,它无法继续增加 QLabel
的高度,并削减关闭顶部和底部的一些文本。
This answer 试图解决本质上相同的问题,其中涉及将 QLabel
的垂直 sizePolicy()
设置为 MinimumExpanding
,而这个 技术上 有效,但它会强制 QLabels
尝试填充整个 QScrollArea
视口,如果视口尚未被 QLabel
填充。
这是当前未将 sizePolicy
设置为 MinimumExpanding
的样子(注意第一个 QLabel
):
下面是将 MinimumExpanding
设置为 QLabel
的垂直尺寸策略时的样子(看起来很棒...):
但是当滚动区域只有几个 QLabel
s 时会导致这种行为,这是不可接受的行为,因为这将是一项 "comments" 服务,人们可以在其中post 他们的纯文本问题:
有没有人有解决此问题的方法,或遇到过类似的问题?
作为参考,这是我的一些代码:
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;
}
""")
这可以通过使用包含新闻项的布局的 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)
spacer 将标签向上推,这会阻止它们拉伸以占用可用的 space。使用 addStretch
的 stretch-factor 参数可确保 spacer 始终优先于布局中的其他项目。
此问题特定于 PyQt5,但 C++ Qt5 答案也很好。
在固定宽度和可变高度的 QScrollArea 中,我有一个包含 QLabel
的 QVBoxLayout
。这些 QLabels
有 setWordWrap(True)
并且包含的文本可能比 QScrollArea
的固定宽度长。当 QLabel
中的文本换行到 ~4 行时,一切正常,但是当 QLabel
需要更多时,它无法继续增加 QLabel
的高度,并削减关闭顶部和底部的一些文本。
This answer 试图解决本质上相同的问题,其中涉及将 QLabel
的垂直 sizePolicy()
设置为 MinimumExpanding
,而这个 技术上 有效,但它会强制 QLabels
尝试填充整个 QScrollArea
视口,如果视口尚未被 QLabel
填充。
这是当前未将 sizePolicy
设置为 MinimumExpanding
的样子(注意第一个 QLabel
):
下面是将 MinimumExpanding
设置为 QLabel
的垂直尺寸策略时的样子(看起来很棒...):
但是当滚动区域只有几个 QLabel
s 时会导致这种行为,这是不可接受的行为,因为这将是一项 "comments" 服务,人们可以在其中post 他们的纯文本问题:
有没有人有解决此问题的方法,或遇到过类似的问题?
作为参考,这是我的一些代码:
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;
}
""")
这可以通过使用包含新闻项的布局的 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)
spacer 将标签向上推,这会阻止它们拉伸以占用可用的 space。使用 addStretch
的 stretch-factor 参数可确保 spacer 始终优先于布局中的其他项目。