Results 1 to 9 of 9

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

  1. #1
    Join Date
    Jan 2010
    Posts
    11
    Thanks
    1
    Thanked 2 Times in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

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

    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 and similarly names can be of variable length.

    Currently I am starting with a maximum font size, checking if it fits and decrementing it until I find a font size that fits. So far, I haven't been able to find a quick and easy way to do this. Is there a better, or more efficient way to do this?

    Thanks!

    Qt Code:
    1. void checkFontSize(QPainter *painter, const QString& name) {
    2. // check the font size - need a better algorithm... this could take awhile
    3. while (painter->fontMetrics().width(name) > rect().width()) {
    4. int newsize = painter->font().pointSize() - 1;
    5. painter->setFont(QFont(painter->font().family(), newsize));
    6. }
    7. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

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

    Hi there!

    Two days ago I solved it with QFont::setPointSizeF like this:

    Qt Code:
    1. float factor = rect().width() / painter->fontMetrics().width(name);
    2. if ((factor < 1) || (factor > 1.25))
    3. {
    4. QFont f = painter->font();
    5. f.setPointSizeF(f.pointSizeF()*factor);
    6. painter->setFont(f);
    7. }
    To copy to clipboard, switch view to plain text mode 
    This assumes, that your fonts width scales like its height. Works fine for me.

    HIH

    Johannes

  3. The following user says thank you to JohannesMunk for this useful post:

    dchow (4th February 2010)

  4. #3
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

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

    This, or something along the same lines seem like the only way to me. Be careful that you don't get a runaway loop with zero or negative font size (width == 0?); not sure what QFontMetrics will make of that.

    An approximation could go like: Pre-calculating the width of an "M" at each point size (Substitute the character set's widest glyph if you are using non-Latin characters). When you get your string, take its length and select the font size that gets length() Ms into the available width. Might be a bit quicker if you call this a lot.

  5. #4
    Join Date
    Jan 2010
    Posts
    11
    Thanks
    1
    Thanked 2 Times in 1 Post
    Qt products
    Qt4
    Platforms
    Windows

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

    Johannes - I just tried out the code snippet you supplied and so far so good! I like how your solution comes up with a good approximation in one pass. Thanks!

  6. #5
    Join Date
    Dec 2010
    Posts
    11
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Symbian S60

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

    I have got the same problem, so I post here since this thread is in good place in Google
    The solution provided by JohannesMunk works well for 1 line of text.
    But what about auto-size text in a specified rectangle, possibly (but not necessary) wraping on multiple lines.
    Do you have a solution for that ?

  7. #6
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

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

    Hi!

    How about using QFontMetrics::boundingRect with the Qt::TextWordWrap flag set?

    The problem will be that word wrapping will usually only occur, after the scaling has been applied.
    So the text will not be wrapped when called the first time.

    Mmh..

    Johannes
    Last edited by JohannesMunk; 4th February 2011 at 19:20.

  8. #7
    Join Date
    Feb 2007
    Location
    Karlsruhe, Germany
    Posts
    469
    Thanks
    17
    Thanked 90 Times in 88 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

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

    I needed this functionality myself - here is what I came up with:

    Qt Code:
    1. qreal lod = option->levelOfDetailFromTransform(painter->worldTransform());
    2. QRectF r = boundingRect();
    3. QFont f = painter->font();
    4. qreal aspectRatio = painter->fontMetrics().lineSpacing() / painter->fontMetrics().averageCharWidth();
    5. int pixelsize = sqrt(r.width()*r.height()/aspectRatio/(stitle.length()*3))*aspectRatio;
    6. f.setPixelSize(pixelsize);
    7. int flags = Qt::AlignCenter|Qt::TextDontClip|Qt::TextWordWrap;
    8. if ((pixelsize * lod) < 13)
    9. flags |= Qt::TextWrapAnywhere;
    10. QRectF tbr = fm.boundingRect(r,flags,stitle);
    11. pixelsize = f.pixelSize()*qMin(r.width()*0.95/tbr.width(),r.height()*0.95/tbr.height());
    12. f.setPixelSize(pixelsize);
    13. painter->setFont(f);
    14. painter->drawText(r,flags,stitle);
    To copy to clipboard, switch view to plain text mode 
    The idea of the first attempt to calculate a pixelsize is to calculate how big a letter can be if you want to distribute a certain amount of letters on the available space.

    numberOfLetters = width / charWidth * height / (charWidth*aspectRatio)

    => pixelSize = charWidth * aspectRatio = sqrt ( width * height / numberOfLetters / aspectRatio) * aspectRatio;

    For my scenario numberOfLetters is 3 times the amount of text I want to display, because I don't want to cover the whole item with text.

    With this guess I call QFontMetricF::boundingRect and fine tune the result accordingly.

    This works fine for my purpose.

    HIH

    Johannes
    Last edited by JohannesMunk; 5th February 2011 at 14:42.

  9. #8
    Join Date
    Jul 2010
    Posts
    37
    Thanks
    13
    Qt products
    Qt4
    Platforms
    Windows

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

    Quote Originally Posted by JohannesMunk View Post
    This works fine for my purpose.
    I'm confirming you that this solution (i named it the 2nd) fit at the best my requirements too.
    Here is my two solutions comparison:
    solutioncomparison.jpg

    My scene doesn't has too much items, so the drawing performances are acceptable.
    Thank you guys for shared your work.

  10. #9
    Join Date
    Mar 2016
    Posts
    1
    Qt products
    Qt4
    Platforms
    Unix/X11

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

    Hi Johannes / All

    Could you please explain the math behind this?

    "numberOfLetters = width / charWidth * height / (charWidth*aspectRatio)

    => pixelSize = charWidth * aspectRatio = sqrt ( width * height / numberOfLetters / aspectRatio) * aspectRatio;
    "

    I don't follow it.

    Thank you

    Tim

Similar Threads

  1. QVBoxLayout width size limit
    By QPlace in forum Qt Programming
    Replies: 7
    Last Post: 18th June 2009, 17:41
  2. Scale size of QGraphicsItem without scaling pen width
    By Lodorot in forum Qt Programming
    Replies: 1
    Last Post: 25th May 2009, 01:18
  3. QLabel auto width?
    By DiamonDogX in forum Qt Programming
    Replies: 3
    Last Post: 14th April 2009, 08:25
  4. changing the size of the tab width: QTabWidget
    By nikita in forum Qt Programming
    Replies: 2
    Last Post: 29th August 2006, 09:31
  5. How to get size (length, width ....) of string or char
    By Krishnacins in forum Qt Programming
    Replies: 1
    Last Post: 20th March 2006, 10:55

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.