Qt获得适合固定QRect内部的大QString的子串

时间:2015-12-01 15:27:02

标签: qt text word-wrap

我有一个大字符串,一个固定字体和一个固定的矩形来绘制该字符串。

  • 如果字符串不合适,我想知道适合该矩形的子字符串的长度
  • 如果字符串确实适合,那么我想知道边界矩形高度

我整天搜索网络,一无所获。

2 个答案:

答案 0 :(得分:1)

使用QFontMetrics类及其boundingRect类,获取提供的字符串使用的矩形

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

将边界的大小与测试字符串适合的区域进行比较。

  

如果字符串不合适,我想知道适合该矩形的子字符串的长度

如果boundingRect返回的rect的边界太大,则递归删除字符,直到宽度适合目标rect。

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返回的rect的高度。

int height = bounds.height();

答案 1 :(得分:1)

我发布了自己的二进制搜索算法。 Batman指出正确的方向,谢谢!

顺便说一句,如果你愿意,你可以使用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;
}