我有一个QLabel元素在一个小部件,可以调整大小。文本可能会溢出边界,所以我需要让应用程序看起来更优雅,让文本在文本中最后一个完全可见的单词之后生成省略号(…)。
在HTML/CSS中制作布局我曾经使用text-overflow: ellipsis;
,但对于QT类,我没有找到关于这方面的任何信息。
看起来在标签大小调整事件中,您可以使用小部件的新宽度创建省略文本并重置文本。使用QFontMetrics::elidedText方法获取省略的字符串版本。
QString text("some long text without elipsis");
QFontMetrics metrics(label->font());
QString elidedText = metrics.elidedText(text, Qt::ElideRight, label->width());
label->setText(elidedText);
希望这对你有帮助
我已经修改了上面描述的解决方案并创建了一个函数:
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);
}
希望对大家有用。
Qt-5包含一个省略的标签类示例,在实现您自己的标签类时可能是一个有用的参考。
来自示例:
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);
}
}
我就是这样做到的。就像普通的QLabel一样,只是有省略号。
class EllipsisLabel : public QLabel
{
Q_OBJECT
public:
explicit EllipsisLabel(QWidget *parent = nullptr);
explicit EllipsisLabel(QString text, QWidget *parent = nullptr);
void setText(QString);
protected:
void resizeEvent(QResizeEvent *);
private:
void updateText();
QString m_text;
};
EllipsisLabel::EllipsisLabel(QWidget *parent)
: EllipsisLabel("", parent)
{
}
EllipsisLabel::EllipsisLabel(QString text, QWidget *parent)
: QLabel(parent)
{
setText(text);
}
void EllipsisLabel::setText(QString text)
{
m_text = text;
updateText();
}
void EllipsisLabel::resizeEvent(QResizeEvent *event)
{
QLabel::resizeEvent(event);
updateText();
}
void EllipsisLabel::updateText()
{
QFontMetrics metrics(font());
QString elided = metrics.elidedText(m_text, Qt::ElideRight, width());
QLabel::setText(elided);
}