Открих, че отговорът на @Eric Hulser, макар и страхотен, не работи, когато етикетът беше поставен в друга джаджа.
Измислих това, като хакнах заедно отговора на Ерик и Qt Пример за заличен етикет. Както е написано тук, той позволява преминаването на различни elide режими и запазва текста вертикално (разбира се, елидиран е хоризонтално!).
Фазата на оформлението, внедрена съгласно към документите, не ми е ясно, така че не мога да говоря с това много добре. По принцип той проверява дали текстът на етикета не надхвърля ширината на етикета; ако го направи, той премахва текста.
Също така не е ясно какво се има предвид под валиден ред. Премахването на тези проверки води до срив на приложението. Предполагам, че линията е валидна, когато не се простира отвъд джаджата.
Ако искате да използвате 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