Search
Write a publication
Pull to refresh

Qt. Ограничение многострочного текста прямоугольником

В библиотеке Qt есть замечательная функция QFontMetrics::elidedText. Она позволяет ограничить текст по ширине, а все, что не влезает заменить на символ "...". В одном из проектов мне потребовалось реализовать аналогичное поведение, но текст мог быть многострочным, а ограничивать его надо было прямоугольником.


Приведу здесь решение без изменений, ведь главное — понять его суть, а дальше вы можете адаптировать его под собственные нужды. Сразу хочу заметить, что этот код плохо работает с текстом содержащим символы переноса строки.

Данная функция принимает на вход QLabel, который надо заполнить, длинный текст, который надо ограничить и небольшой дополнительный текст. Например, если передать «очень длинный текст» и дополнительно «коротенький», то в текст QLabel будет занесено что-то вроде: «очень длинн… коротенький».

void DataAdapter::setText( QLabel* label, const QString& text, const QString& additional ) const
{
QFontMetrics fm = label->fontMetrics();
int addWidth = fm.width(additional);
int leading = fm.leading();
int height = 0;
QRect rect = label->contentsRect();
QString elided;
QTextLayout layout(text, label->font());
layout.beginLayout();
for (QTextLine line = layout.createLine(); line.isValid(); line = layout.createLine())
{
line.setLineWidth(rect.width());
height += leading;
line.setPosition(QPointF(0, height));
height += line.height();
if (height + leading + line.height() < rect.height())
{
QString s = layout.text().mid(line.textStart(), line.textLength());
// Если в строке есть слово, которое шире выделенного прямоугольника, то его надо ограничить
elided += line.naturalTextWidth() > rect.width() ? fm.elidedText(s, Qt::ElideRight, rect.width()) : s;
}
else
{
QString s = layout.text().mid(line.textStart());
elided += fm.elidedText(s, Qt::ElideRight, rect.width() - addWidth);
break;
}
}
layout.endLayout();
label->setText(elided + additional);
}
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.