这个功能很有用,默认情况下文本超出长度会被直接截断的,给用户体验很不好。这里截断后会显示...,并且鼠标划上去有tooltip。

#ifndef ELIDEDLABEL_H
#define ELIDEDLABEL_H

#include <QtWidgets/QFrame>
#include <QtCore/QRect>
#include <QtGui/QResizeEvent>
#include <QtCore/QString>
#include <QtWidgets/QWidget>

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) override;

private:
    bool elided;
    QString content;
};

#endif // TEXTWRAPPINGWIDGET_H
#include "elidedlabel.h"

#include <QPainter>
#include <QTextLayout>
#include <QDebug>

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 = 3;

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

        if (!line.isValid())
            break;

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

        // 只处理单行
        if (0 && height() >= nextLineY + lineSpacing) {
            line.draw(&painter, QPoint(0, y));
            y = nextLineY;
        } 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 = (lastLine != elidedLastLine);
            break;
        }
    }
    textLayout.endLayout();

    if (didElide) {
        elided = didElide;
    }
    this->setToolTip(didElide ? content : "");
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

鄂ICP备17003086号. Copyright © 2016. All Rights Reserved.