PySide2中QLabel开启自动换行后调整大小时高度不更新、文本裁剪如何修复?
问题原因
- 之前的修复代码错误使用
setMaximumHeight限制了QLabel的最大高度,而非设置最小高度保证内容完整展示 - 仅修改QLabel高度后未触发父布局的重新计算,布局仍然按照原有尺寸渲染导致内容被裁剪
- 顶层控件初始化时设置的固定高度70远小于文本渲染需要的最小高度,布局没有自动适配内容高度的逻辑
- 文本内容的HTML标签被转义,导致QLabel无法正确渲染富文本,也会额外增加不必要的内容高度
修复方案
按照以下步骤调整代码即可解决问题:
- 调整QLabel的大小策略,让它可以根据内容调整高度
- 修正resizeEvent逻辑,设置QLabel的最小高度,同时触发父布局重排
- 移除顶层控件的固定高度限制,允许布局自动适配内容尺寸
- 修正富文本的转义字符,让QLabel可以正确渲染样式
完整修改后的代码
''' Main Navigation bar ''' ################################################################################ # imports ################################################################################ import os import sys import inspect from PySide2 import QtWidgets, QtCore, QtGui ################################################################################ # widgets ################################################################################ class Context(QtWidgets.QWidget): def __init__(self): super(Context, self).__init__() # controls self.uiThumbnail = QtWidgets.QLabel() self.uiThumbnail.setMinimumSize(QtCore.QSize(100, 75)) self.uiThumbnail.setMaximumSize(QtCore.QSize(100, 75)) self.uiThumbnail.setScaledContents(True) self.uiThumbnail.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.uiThumbnail.setObjectName('thumbnail') self.uiDetailsText = QtWidgets.QLabel() self.uiDetailsText.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) self.uiDetailsText.setWordWrap(True) self.uiDetailsText.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) self.uiDetailsText.setOpenExternalLinks(True) # 调整大小策略:垂直方向根据内容自动调整最小高度 self.uiDetailsText.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum) self.uiMenuButton = QtWidgets.QPushButton() self.uiMenuButton.setFixedSize(QtCore.QSize(24, 24)) self.uiMenuButton.setFocusPolicy(QtCore.Qt.NoFocus) # header layout self.headerLayout = QtWidgets.QHBoxLayout() self.headerLayout.setSpacing(6) self.headerLayout.setContentsMargins(6, 6, 6, 6) self.headerLayout.setAlignment(QtCore.Qt.AlignTop) self.headerLayout.addWidget(self.uiThumbnail) self.headerLayout.addWidget(self.uiDetailsText) self.headerLayout.addWidget(self.uiMenuButton) self.headerLayout.setAlignment(self.uiThumbnail, QtCore.Qt.AlignTop) self.headerLayout.setAlignment(self.uiMenuButton, QtCore.Qt.AlignTop) # frames self.headerFrame = QtWidgets.QFrame() self.headerFrame.setObjectName('panel') self.headerFrame.setFrameShape(QtWidgets.QFrame.StyledPanel) self.headerFrame.setFrameShadow(QtWidgets.QFrame.Raised) self.headerFrame.setLayout(self.headerLayout) # layout self.mainLayout = QtWidgets.QHBoxLayout() self.mainLayout.setSpacing(6) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.addWidget(self.headerFrame) self.setLayout(self.mainLayout) self.setStyleSheet(''' #thumbnail { background-color: rgb(70,70,70); } #panel { background-color: rgb(120,120,120); border-radius:3px; } ''') self.updateContext() # 修正后的resizeEvent逻辑 def resizeEvent(self, event): # 计算当前宽度下文本需要的完整高度 required_height = self.uiDetailsText.heightForWidth(self.uiDetailsText.width()) # 设置QLabel的最小高度为需要的高度,保证内容不会被裁剪 self.uiDetailsText.setMinimumHeight(required_height) # 触发父布局重新计算尺寸 self.adjustSize() super().resizeEvent(event) # methods def updateContext(self): # 修正转义字符,让富文本可以正常渲染 self.uiDetailsText.setText(''' <span style="font-size:14px;"> <b>A title goes here which can wrap</b> </span> <br> <span style="font-size:11px;"> <b>Status:</b> Additional details go here <br> <b>User:</b> User information goes here <br> <b>About:</b> Some more information <br> <b>Date:</b> 2021-07-03 <br> </span> ''') ################################################################################ # main ################################################################################ if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) ex = Context() # 移除固定高度限制,只设置宽度,高度由内容自动适配 ex.resize(500, ex.minimumHeight()) ex.show() sys.exit(app.exec_())
适配QDialog的注意事项
如果将该控件放到QDialog中,需要给QDialog的布局设置大小约束QLayout.SetMinimumSize,保证对话框可以随着内容高度自动调整最小尺寸:
dialog = QtWidgets.QDialog() layout = QtWidgets.QVBoxLayout(dialog) layout.addWidget(Context()) # 设置布局最小尺寸约束 layout.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize) dialog.show()
内容的提问来源于stack exchange,提问作者JokerMartini
相关产品推荐
相关产品推荐

