For Qt 4.6.x, how to auto-size text to fit in a specified width?

前端 未结 8 1085
情书的邮戳
情书的邮戳 2020-12-31 04:11

Inside of my QGraphicsRectItem::paint(), I am trying to draw the name of the item within its rect(). However, for each of the different items, they can be of variable width

相关标签:
8条回答
  • 2020-12-31 04:46

    Follow function based on the answer and comment to the answer allow optimizing font size to fit text in specified rectangle:

    QFont optimizeFontSizeToFitTextInRect(QPainter * painter, QRectF drawRect, QString text, int flags = Qt::TextDontClip|Qt::TextWordWrap, double goalError =  0.01, int maxIterationNumber=10){
        painter->save();
    
        QRect fontBoundRect;
        QFont font;
        double minError = std::numeric_limits<double>::max();
        double error = std::numeric_limits<double>::max();
        int iterationNumber=0;
        while((error > goalError) && (iterationNumber<maxIterationNumber)){
            iterationNumber++;
            fontBoundRect = painter->fontMetrics().boundingRect(drawRect.toRect(),flags, text);
            double xFactor = drawRect.width() / fontBoundRect.width();
            double yFactor = drawRect.height() / fontBoundRect.height();
            double factor;
            if (xFactor<1 && yFactor<1) {
                factor = std::min(xFactor,yFactor);
            } else if (xFactor>1 && yFactor>1) {
                factor = std::max(xFactor,yFactor);
            } else if (xFactor<1 && yFactor>1) {
                factor = xFactor;
            } else {
                factor = yFactor;
            }
            error = abs(factor-1);
            if (factor > 1 ) {
                if (error < minError) {
                    minError = error;
                } else {
                    break;
                }
            }
            font = painter->font();
            font.setPointSizeF(font.pointSizeF()*factor);
            painter->setFont(font);
        }
        painter->restore();
    
        return font;
    }
    
    0 讨论(0)
  • 2020-12-31 04:48

    Unfortunately, no. There's no easy solution to this. The most obvious improvement, performance-wise would be calculate and cache the needed font size when the text is changed instead of recalculating it in each paintEvent. Another improvement would be to try to estimate the correct size based on the proportions of the bounding rect. Making and testing estimates should get you to correct size much quicker than simply decrementing the point size by one each iteration.

    0 讨论(0)
提交回复
热议问题