Question

I have got a QLabel element in a widget which can be resized. The text can overflow boundaries, so I need, for the application to look more elegant, some way to make the text generate an ellipsis (...) after the last totally visible word in the text.

Making layouts in HTML/CSS I used to use text-overflow: ellipsis; for this, but for QT classes I have not found any information on this.

Was it helpful?

Solution

It looks like on your label resize event you can create elided text using the new width of the widget and reset the text. Use QFontMetrics::elidedText method to get the elided version of the string.

QString text("some long text without elipsis");
QFontMetrics metrics(label->font());
QString elidedText = metrics.elidedText(text, Qt::ElideRight, label->width());
label->setText(elidedText);

hope this helps, regards

OTHER TIPS

I've modified solution described above and created a function:

static void SetTextToLabel(QLabel *label, QString text)
{
    QFontMetrics metrix(label->font());
    int width = label->width() - 2;
    QString clippedText = metrix.elidedText(text, Qt::ElideRight, width);
    label->setText(clippedText);
}

Hope it will be useful.

Qt-5 includes an example of an elided label class which may be a useful reference when implementing your own.

From the example:

elidedlabel.h:

class ElidedLabel : public QFrame
{
    Q_OBJECT
    Q_PROPERTY(QString text READ text WRITE setText)
    Q_PROPERTY(bool isElided READ isElided)

public:
    explicit ElidedLabel(const QString &text, QWidget *parent = 0);

    void setText(const QString &text);
    const QString & text() const { return content; }
    bool isElided() const { return elided; }

protected:
    void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;

signals:
    void elisionChanged(bool elided);

private:
    bool elided;
    QString content;
};

elidedlabel.cpp:

ElidedLabel::ElidedLabel(const QString &text, QWidget *parent)
    : QFrame(parent)
    , elided(false)
    , content(text)
{
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
}

void ElidedLabel::setText(const QString &newText)
{
    content = newText;
    update();
}

void ElidedLabel::paintEvent(QPaintEvent *event)
{
    QFrame::paintEvent(event);

    QPainter painter(this);
    QFontMetrics fontMetrics = painter.fontMetrics();

    bool didElide = false;
    int lineSpacing = fontMetrics.lineSpacing();
    int y = 0;

    QTextLayout textLayout(content, painter.font());
    textLayout.beginLayout();
    forever {
        QTextLine line = textLayout.createLine();

        if (!line.isValid())
            break;

        line.setLineWidth(width());
        int nextLineY = y + lineSpacing;

        if (height() >= nextLineY + lineSpacing) {
            line.draw(&painter, QPoint(0, y));
            y = nextLineY;
            //! [2]
            //! [3]
        } else {
            QString lastLine = content.mid(line.textStart());
            QString elidedLastLine = fontMetrics.elidedText(lastLine, Qt::ElideRight, width());
            painter.drawText(QPoint(0, y + fontMetrics.ascent()), elidedLastLine);
            line = textLayout.createLine();
            didElide = line.isValid();
            break;
        }
    }
    textLayout.endLayout();

    if (didElide != elided) {
        elided = didElide;
        emit elisionChanged(didElide);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top