2015-12-01 3 views
3

У меня есть большая строка, фиксированный шрифт и фиксированный прямоугольник, чтобы нарисовать эту строку.Qt получает подстроку большой QString, которая помещается внутри фиксированного QRect

  • Если строка не подходит, я хотел бы знать длину подстроки, которая вписывается в этот прямоугольник
  • если строка делает нужной, то я хотел бы знать, ограничивающей высоту прямоугольника

Я искал в Интернете весь день и ничего не нашел.

+1

'QFontMetrics :: boundingRect' и эвристика? – peppe

+1

Я могу создать бинарный поиск, подобный алгоритму, чтобы найти подстроку, которая подходит для использования boundingRect(), но я предполагаю, что она может быть очень неэффективной. – Borzh

ответ

1

Используя QFontMetrics класс и его boundingRect класс, получить прямоугольник, используемый в строке при условии

// assumes myFont has been instantiated 
QFontMetrics fm(myFont); 
QRect bounds = fm.boundingRect("Some text here"); 

Сравните размер границ с областью, с которой, чтобы проверить, если строка будет соответствовать.

Если строка не подходит, я хотел бы знать длину подстроки, которая вписывается в этот прямоугольник

Если границы возвращенного прямоугольнику из boundingRect слишком велики, рекурсивно удалить символов до тех пор, пока ширина не окажется в вашем целевом прямоугольнике.

bool bFits = false; 
QString str = "String to test boundary"; 
QFontMetrics fm(myFont); 
QRect bounds; 
do 
{  
    bounds = fm.boundingRect(str); 
    // Assume testBoundary is the defined QRect of the area to hold the text 
    if(!testBoundary.contains(bounds) && (!str.isEmpty()) ) 
     str.chop(1); 
    else 
     bFits = true; 
}while(!bFits); 

если строка делает нужным, то я хотел бы знать, ограничивающей высоту прямоугольника

Это просто высота возвращенного прямоугольнику от вызова boundingRect.

int height = bounds.height(); 
+0

Проблема в том, что я знаю, что строка не подходит. Я хотел бы знать максимальную подстроку длины, которая подходит. – Borzh

+0

В соответствии с обновленным ответом в цикле удалите символы строки до ее соответствия. – TheDarkKnight

+0

Это произошло и со мной, но я предполагаю, что удаление символов/слов/строк будет довольно неэффективным, так как алгоритм всегда вычисляет ограничивающий прямоугольник той же строки. Есть ли другой способ рассчитать это? – Borzh

1

Я отправляю свой собственный алгоритм бинарного поиска. Batman указал в правильном направлении, спасибо!

BTW вы можете использовать QFontMetrics вместо QPainter, если хотите.

int FontUtils::FittingLength(const QString& s, QPainter &p, const QRectF& rect, 
          int flags/* = Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap*/) 
{ 
    QRectF r = p.boundingRect(rect, flags, s); 
    if (r.height() <= rect.height()) // String fits rect. 
     return s.length(); 

    // Apply binary search. 
    QString sub; 
    int left = 0, right = s.length()-1; 
    do 
    { 
     int pivot = (left + right)>>1; // Middle point. 
     sub = s.mid(0, pivot+1); 
     r = p.boundingRect(rect, flags, sub); 

     if (r.height() > rect.height()) // Doesn't fit. 
      right = pivot-1; 
     else 
      left = pivot+1; 
    } while (left < right); 

    left++; // Length of string is one char more. 

    // Remove trailing word if it doesn't fit. 
    if (!s.at(left).isSpace() && !s.at(left+1).isSpace()) 
    { 
     while ((--left > 0) && !sub.at(left).isSpace()); 
     left++; 
    } 

    return left; 
}