Qt获取适合固定QRect的大型QString的子字符串

Qt获取适合固定QRect的大型QString的子字符串,qt,text,word-wrap,Qt,Text,Word Wrap,我有一个大字符串,一个固定的字体和一个固定的矩形来画那个字符串 如果字符串不合适,我想知道适合该矩形的子字符串的长度 如果字符串合适,那么我想知道边界矩形的高度 我搜索了一整天,没有找到任何东西。使用类及其boundingRect类,获取所提供字符串使用的rect // assumes myFont has been instantiated QFontMetrics fm(myFont); QRect bounds = fm.boundingRect("Some text here");

我有一个大字符串,一个固定的字体和一个固定的矩形来画那个字符串

  • 如果字符串不合适,我想知道适合该矩形的子字符串的长度
  • 如果字符串合适,那么我想知道边界矩形的高度
我搜索了一整天,没有找到任何东西。

使用类及其boundingRect类,获取所提供字符串使用的rect

// 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();

我正在发布我自己的二进制搜索算法<代码>蝙蝠侠指出了正确的方向,谢谢

顺便说一句,如果需要,您可以使用
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;
}
int-FontUtils::FittingLength(常量QString&s、QPainter&p、常量QRectF&rect、,
int flags/*=Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap*/)
{
qrectfr=p.boundingRect(rect,flags,s);
如果(r.height()>1;//中间点。
sub=s.mid(0,枢轴+1);
r=p.boundingRect(rect,flags,sub);
如果(r.height()>rect.height())//不合适。
右=枢轴-1;
其他的
左=枢轴+1;
}而(左<右);
左+++;//字符串的长度是多一个字符。
//如果尾随词不合适,请将其删除。
如果(!s.at(左).isSpace()和&!s.at(左+1).isSpace())
{
而((-left>0)和&&!sub.at(left).isSpace();
左++;
}
左转;
}

QFontMetrics::boundingRect
和启发式?我可以创建一个类似于二进制搜索的算法,使用boundingRect()查找适合的子字符串,但我认为这可能会非常低效。问题是我知道字符串不合适。我想知道适合的最大长度子字符串。正如更新的答案所述,在循环中删除字符串的字符,直到合适为止。除非字符串非常长,否则性能可以忽略不计。您不应该太担心在你注意到这样一个问题之前,你可以在需要的时候分析你的应用程序并进行优化。当然,注意好的编程不是一件坏事,但在这里不应该是一个问题。将计算结果绘制到rect大小的像素图可能是一个好主意。在未来的绘画活动中,你只需要需要使用QPaint::drawPixmap绘制该pixmap。只有在字符串或rect大小更改时才重新绘制该pixmap。这可以大大加快绘制速度。这意味着将计算从绘制事件中排除。简单的优化是执行“二进制搜索”以查找最大长度,而不是切块(1)。