[SOLVED] PySide/PyQt truncate text in QLabel based on minimumSize

Issue

I am wondering how to best truncate text in a QLabel based on it’s maximum width/height.
The incoming text could be any length, but in order to keep a tidy layout I’d like to truncate long strings to fill a maximum amount of space (widget’s maximum width/height).

E.g.:

 'A very long string where there should only be a short one, but I can't control input to the widget as it's a user given value'

would become:

'A very long string where there should only be a short one, but ...'

based on the required space the current font needs.

How can I achieve this best?

Here is a simple example of what I’m after, though this is based on word count, not available space:

import sys
from PySide.QtGui import *
from PySide.QtCore import *


def truncateText(text):
    maxWords = 10
    words = text.split(' ')
    return ' '.join(words[:maxWords]) + ' ...'

app = QApplication(sys.argv)

mainWindow = QWidget()
layout = QHBoxLayout()
mainWindow.setLayout(layout)

text = 'this is a very long string, '*10
label = QLabel(truncateText(text))
label.setWordWrap(True)
label.setFixedWidth(200)
layout.addWidget(label)

mainWindow.show()
sys.exit(app.exec_())

Solution

Even easier – use the QFontMetrics.elidedText method and overload the paintEvent, here’s an example:

from PyQt4.QtCore import Qt
from PyQt4.QtGui import QApplication,\
                        QLabel,\
                        QFontMetrics,\
                        QPainter

class MyLabel(QLabel):
    def paintEvent( self, event ):
        painter = QPainter(self)

        metrics = QFontMetrics(self.font())
        elided  = metrics.elidedText(self.text(), Qt.ElideRight, self.width())

        painter.drawText(self.rect(), self.alignment(), elided)

if ( __name__ == '__main__' ):
    app = None
    if ( not QApplication.instance() ):
        app = QApplication([])

    label = MyLabel()
    label.setText('This is a really, long and poorly formatted runon sentence used to illustrate a point')
    label.setWindowFlags(Qt.Dialog)
    label.show()

    if ( app ):
        app.exec_()

Answered By – Eric Hulser

Answer Checked By – Timothy Miller (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *