QLabel 是一个非常简洁的小部件:它看起来非常简单,但实际上并非如此。
大小和显示方面非常重要:因为它能够显示格式化文本,它甚至可以有一些layout issues。
由于您的要求是使标签尽可能小(但尽可能保持其内容显示),因此最重要的要求是实现sizeHint(和minimumSizeHint())函数,因为父小部件在调整其内容大小时会考虑这一点。
可能的解决方案基于两个方面:
- 提供不考虑全部内容的基本 [最小] 大小提示
- 当可用空间不足时,通过删除文本来覆盖绘画
以下代码显然不考虑富文本格式,包括不同的段落对齐方式、自动换行等。
这是一个显示子类 QLabel 尝试显示以下路径的示例:
'/tmp/test_dir/some_long_path/some_subdir/imagepath/'
考虑一下,您甚至可以实际使用基本的 QWidget。在下面的代码中,我正在考虑 QFrame 子类化功能,其中还包括添加适当的边距和边框,具体取决于样式和 frameShape 或 frameShadow 属性。
class ElideLabel(QtWidgets.QLabel):
_elideMode = QtCore.Qt.ElideMiddle
def elideMode(self):
return self._elideMode
def setElideMode(self, mode):
if self._elideMode != mode and mode != QtCore.Qt.ElideNone:
self._elideMode = mode
self.updateGeometry()
def minimumSizeHint(self):
return self.sizeHint()
def sizeHint(self):
hint = self.fontMetrics().boundingRect(self.text()).size()
l, t, r, b = self.getContentsMargins()
margin = self.margin() * 2
return QtCore.QSize(
min(100, hint.width()) + l + r + margin,
min(self.fontMetrics().height(), hint.height()) + t + b + margin
)
def paintEvent(self, event):
qp = QtGui.QPainter(self)
opt = QtWidgets.QStyleOptionFrame()
self.initStyleOption(opt)
self.style().drawControl(
QtWidgets.QStyle.CE_ShapedFrame, opt, qp, self)
l, t, r, b = self.getContentsMargins()
margin = self.margin()
try:
# since Qt >= 5.11
m = self.fontMetrics().horizontalAdvance('x') / 2 - margin
except:
m = self.fontMetrics().width('x') / 2 - margin
r = self.contentsRect().adjusted(
margin + m, margin, -(margin + m), -margin)
qp.drawText(r, self.alignment(),
self.fontMetrics().elidedText(
self.text(), self.elideMode(), r.width()))