头文件:
#ifndef ELIDEDLABEL_H
#define ELIDEDLABEL_H
#include <QFrame>
#include <QRect>
#include <QResizeEvent>
#include <QString>
#include <QWidget>
class ElidedLabel : public QFrame
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText)
Q_PROPERTY(bool isElided READ isElided)
public:
ElidedLabel(QWidget *parent = 0);
void setText(const QString &text);
const QString & text() const { return content; }
bool isElided() const { return elided; }
protected:
void paintEvent(QPaintEvent *event);
signals:
void elisionChanged(bool elided);
private:
bool elided;
QString content;
};
#endif // TEXTWRAPPINGWIDGET_H
源文件:
#include <QPainter>
#include <QTextLayout>
#include <QDebug>
ElidedLabel::ElidedLabel(QWidget *parent)
: QFrame(parent)
, elided(false)
{
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
}
void ElidedLabel::setText(const QString &newText)
{
// setToolTip(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;
} 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);
}
}
文本内容随着控件的大小改变,可获取改变前的文本。
下面附上改变文本长度的代码,适合各种控件:
QFont font(ui->_signIn->font());
QFontMetrics fm(font);
ui->_signIn->setText(fm.elidedText(QString(signIn.c_str()),
Qt::ElideRight, ui->_signIn->width()));