Andrés Marafioti
Andrés Marafioti

Reputation: 952

How to elide a rich text after multiple lines in Qt?

I am trying to elide rich text (with html type links) using Qt and Pyside. The text strings will be something like this:

u"<a href='FRIEND' style=\"text-decoration: none\">" \
u"<font color=#1abc9c>{}</font></a> agregó <a href='LINK' " \
u"style=\"text-decoration: none\"><font color=#1abc9c>{}</font></a>" \
u" a su biblioteca".format(EntityMocks.friendMock.display_name,
                           EntityMocks.assetMock1.title) 

The documentation of Qt explicitly states that this cannot be done using rich text so I am stripping my text of all the html tags before passing it to Qt´s elider. I am also trying to accomplish this for texts that will elide on multiple lines. This is my test code for just two lines:

class DoubleElidedText(QLabel):
    def __init__(self, *args):
        super(DoubleElidedText, self).__init__(*args)

    def setText(self, text):
        self.setToolTip(text)
        self.update()

        metrics = QFontMetrics(self.font())
        elide = metrics.elidedText(strip_tags(text), Qt.ElideRight, self.width()*2 - self.width()/5)
        if metrics.width(elide) > self.width():
            self.setMinimumHeight(metrics.height()*2)
        else:
            self.setMinimumHeight(metrics.height())

        texto = u"{}".format(elide)
        super(DoubleElidedText, self).setText(texto)


class MLStripper(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.reset()
        self.fed = []
    def handle_data(self, d):
        self.fed.append(d)
    def get_data(self):
        return ''.join(self.fed)

def strip_tags(html):
    s = MLStripper()
    s.feed(html)
    return s.get_data()

This behavior (stripping the html tags) has become unacceptable for my software.

I am trying to develop a way to elide the rich text that will be displayed in a QLabel with multiple lines. Doing this manually raises one particular issue that I am not being able to solve:

What is the length of the displayed lines? (It will depend on the white space added at the end of every line).

Am I addressing this issue correctly or is there some QtMagic that is missing in my research?

Upvotes: 2

Views: 1303

Answers (1)

Raven
Raven

Reputation: 3516

Not a Python solution but I assume that my approach from https://stackoverflow.com/a/66412942/3907364 can be ported to Python very easily.

In short: Use a QTextDocument to parse and represent the rich text and then use a QTextCursor to keep removing characters from it until it has the desired width.

Note this does not specifically deal with multiline Strings (in fact my answer focuses on single-line Strings), but I would assume extending it to multiline input should be doable.

Upvotes: 1

Related Questions