Я обнаружил, что ответ @Eric Hulser, хотя и отличный, не работает, когда метка помещается в другой виджет.
Я придумал это, объединив ответ Эрика и Qt Пример ярлыка с пропуском. Как написано здесь, он позволяет передавать различные режимы пропуска и сохраняет текст по вертикали (конечно, он удаляется по горизонтали!).
Этап компоновки реализован в соответствии с к документам, мне непонятно, поэтому я не могу говорить об этом очень хорошо. По сути, он проверяет, не выходит ли текст метки за пределы ширины метки; если это так, он исключает текст.
Также неясно, что имеется в виду под допустимая строка. Удаление этих проверок приводит к сбою приложения. Я предполагаю, что линия действительна, когда она не выходит за пределы виджета.
Если вы хотите использовать PySide,
- PyQt5 -> PySide2
- pyqtSignal -> Сигнал
В любом случае, наслаждайтесь!
import sys
from PyQt5 import QtCore, QtWidgets, QtGui
class EliderLabel(QtWidgets.QLabel):
elision_changed = QtCore.pyqtSignal(bool)
def __init__(self, text='', mode=QtCore.Qt.ElideRight, **kwargs):
super().__init__(**kwargs)
self._mode = mode
self.elided = False
self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
self.setText(text)
def setText(self, text):
self._contents = text
# Changing the content require a repaint of the widget (or so
# says the overview)
self.update()
def text(self):
return self._contents
def minimumSizeHint(self):
metrics = QtGui.QFontMetrics(self.font())
return QtCore.QSize(0, metrics.height())
def paintEvent(self, event):
super().paintEvent(event)
did_elide = False
painter = QtGui.QPainter(self)
font_metrics = painter.fontMetrics()
# fontMetrics.width() is deprecated; use horizontalAdvance
text_width = font_metrics.horizontalAdvance(self.text())
# Layout phase, per the docs
text_layout = QtGui.QTextLayout(self._contents, painter.font())
text_layout.beginLayout()
while True:
line = text_layout.createLine()
if not line.isValid():
break
line.setLineWidth(self.width())
if text_width >= self.width():
elided_line = font_metrics.elidedText(self._contents, self._mode, self.width())
painter.drawText(QtCore.QPoint(0, font_metrics.ascent()), elided_line)
did_elide = line.isValid()
break
else:
line.draw(painter, QtCore.QPoint(0, 0))
text_layout.endLayout()
self.elision_changed.emit(did_elide)
if did_elide != self.elided:
self.elided = did_elide
self.elision_changed.emit(did_elide)
class MyDialog(QtWidgets.QWidget):
def __init__(self):
super().__init__()
text = 'This is a really, long and poorly formatted runon sentence used to illustrate a point'
label = EliderLabel(text, parent=self)
label.elision_changed.connect(self.on_elide)
layout = QtWidgets.QVBoxLayout()
layout.addWidget(label)
self.setLayout(layout)
def on_elide(self, val):
print('Elided: ', val, flush=True)
if __name__ == '__main__':
app = QtWidgets.QApplication([])
dia = MyDialog()
dia.show()
sys.exit(app.exec_())
person
Lorem Ipsum
schedule
20.05.2021