18

QGraphicsRectItem::paint() 内で、rect() 内にアイテムの名前を描画しようとしています。ただし、さまざまな項目ごとに幅が可変であり、同様に名前も長さが可変です。

現在、私は最大フォントサイズから始めて、それが収まるかどうかを確認し、収まるフォントサイズが見つかるまで減らしています。これまでのところ、これを行うための迅速かつ簡単な方法を見つけることができませんでした。これを行うためのより良い、またはより効率的な方法はありますか?

ありがとう!

void checkFontSize(QPainter *painter, const QString& name) {
 // check the font size - need a better algorithm... this could take awhile
 while (painter->fontMetrics().width(name) > rect().width()) {
  int newsize = painter->font().pointSize() - 1;
  painter->setFont(QFont(painter->font().family(), newsize));
 }
}
4

8 に答える 8

14

qtcentre.org の Johannes は、次のソリューションを提供しました。

float factor = rect().width() / painter->fontMetrics().width(name);
 if ((factor < 1) || (factor > 1.25))
 {
  QFont f = painter->font();
  f.setPointSizeF(f.pointSizeF()*factor);
  painter->setFont(f);
 }

私は自分のプログラムで試してみましたが、これまでのところ、うまく機能しているようです。1回のパスで結果が得られるので気に入っていますが、フォントの幅が高さのようにスケーリングされることを前提としています。

http://www.qtcentre.org/threads/27839-For-Qt-4-6-x-how-to-auto-size-text-to-fit-in-a-specified-width

于 2010-02-05T01:29:39.733 に答える
3

QGraphicsTextItemをrectアイテムの子として持ち、テキストアイテムの幅を測定してから、テキストアイテムをスケーリングして(setTransform())、rectアイテムの幅(および高さ)に合わせることができます。

于 2010-03-03T09:15:35.743 に答える
2

これが私のコードで、テキストに(高さで)フィットし、非常にうまく機能します(エラー<2%だと思います)

void scalePainterFontSizeToFit(QPainter &painter, QFont &r_font, float _heightToFitIn)
{
    float oldFontSize, newFontSize, oldHeight;

    // Init
    oldFontSize=r_font.pointSizeF();

    // Loop
    for (int i=0 ; i<3 ; i++)
    {
        oldHeight = painter.fontMetrics().boundingRect('D').height();
        newFontSize = (_heightToFitIn / oldHeight) * oldFontSize;
        r_font.setPointSizeF(newFontSize);
        painter.setFont(r_font);
        oldFontSize = newFontSize;
        //qDebug() << "OldFontSize=" << oldFontSize << "HtoFitIn=" << _heightToFitIn << "  fontHeight=" << oldHeight << "  newFontSize=" << newFontSize;
    }

    // End
    r_font.setPointSizeF(newFontSize);
    painter.setFont(r_font);
}
于 2016-07-25T07:42:57.627 に答える
1
void myClass::adaptFontSize(QPainter * painter, int flags, QRectF drawRect, QString text){
     int flags = Qt::TextDontClip|Qt::TextWordWrap; //more flags if needed
     QRect fontBoundRect = 
           painter->fontMetrics().boundingRect(drawRect.toRect(),flags, text);
     float xFactor = drawRect.width() / fontBoundRect.width();
     float yFactor = drawRect.height() / fontBoundRect.height();
     float factor = xFactor < yFactor ? xFactor : yFactor;
     QFont f = painter->font();
     f.setPointSizeF(f.pointSizeF()*factor);
     painter->setFont(f);

 }

またはより正確だが貪欲

 void myClass::adaptFontSize(QPainter * painter, int flags, QRectF rect, QString text, QFont font){
     QRect fontBoundRect;
     fontBoundRect = painter->fontMetrics().boundingRect(rect.toRect(),flags, text);
     while(rect.width() < fontBoundRect.width() ||  rect.height() < fontBoundRect.height()){
         font.setPointSizeF(font.pointSizeF()*0.95);
         painter->setFont(font);
         fontBoundRect = painter->fontMetrics().boundingRect(rect.toRect(),flags, text);
     }
 }
于 2011-07-15T16:35:56.603 に答える
0

残念だけど違う。これには簡単な解決策はありません。最も明らかなパフォーマンスの向上は、テキストが変更されたときに必要なフォント サイズを計算してキャッシュすることです。各 paintEvent で再計算するのではありません。別の改善点は、境界四角形の比率に基づいて正しいサイズを推定しようとすることです。見積もりを作成してテストすることで、反復ごとにポイント サイズを単純に 1 ずつ減らすよりもはるかに迅速にサイズを修正できるはずです。

于 2010-02-04T22:47:19.140 に答える
0

これは、フォント サイズが変化すると予想される範囲によって異なります。範囲が大きい場合、1 ずつインクリメントするのに時間がかかる場合があります。いくつかのポイント サイズの問題であれば、おそらく速度は問題になりません。

範囲が大きい場合は、「1」ではなく、より大きな間隔を追加する別の方法があります。1 つのステップで必要なサイズを超えた場合は、間隔を半分に減らします。毎回、最適なサイズを前後に少しずつ跳ね返ります。連続する 2 つの間隔の差が小さい場合は、終了できます。

これは、ルート検索で使用されるアプローチに似ています。特定のアプリケーションで表示できるフォントのサイズはかなり狭い可能性が高く、すでに使用している力ずくのアプローチではあまり時間がかからないため、やり過ぎかもしれません。

于 2010-04-12T15:20:53.687 に答える