这个功能很有用,默认情况下文本超出长度会被直接截断的,给用户体验很不好。这里截断后会显示…,并且鼠标划上去有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 : "");
}