В библиотеке Qt есть замечательная функция QFontMetrics::elidedText. Она позволяет ограничить текст по ширине, а все, что не влезает заменить на символ "...". В одном из проектов мне потребовалось реализовать аналогичное поведение, но текст мог быть многострочным, а ограничивать его надо было прямоугольником.
Приведу здесь решение без изменений, ведь главное — понять его суть, а дальше вы можете адаптировать его под собственные нужды. Сразу хочу заметить, что этот код плохо работает с текстом содержащим символы переноса строки.
Данная функция принимает на вход QLabel, который надо заполнить, длинный текст, который надо ограничить и небольшой дополнительный текст. Например, если передать «очень длинный текст» и дополнительно «коротенький», то в текст QLabel будет занесено что-то вроде: «очень длинн… коротенький».
Приведу здесь решение без изменений, ведь главное — понять его суть, а дальше вы можете адаптировать его под собственные нужды. Сразу хочу заметить, что этот код плохо работает с текстом содержащим символы переноса строки.
Данная функция принимает на вход 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);
}