@Eric Hulserの答えは素晴らしいものの、ラベルが別のウィジェットに配置されたときに機能しないことがわかりました。
これは、Ericの応答とQt ElidedLabelExampleを一緒にハッキングすることで思いついたものです。ここに書かれているように、さまざまなエリジオンモードを渡すことができ、テキストを垂直方向に保持します(もちろん、水平方向に省略されます!)。
ドキュメントに従って実装されたレイアウトフェーズは私には明確ではないので、私はそれについてうまく話すことができません。基本的に、ラベルテキストがラベルの幅を超えていないことを確認します。含まれている場合は、テキストが削除されます。
また、「有効な」行が何を意味するのかも明確ではありません。これらのチェックを削除すると、アプリがクラッシュします。私の推測では、この線はウィジェットを超えていない場合に有効です。
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_())