Results 1 to 8 of 8

Thread: QLabel Autosizing Reduction

  1. #1
    Join Date
    Apr 2010
    Posts
    27
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Question QLabel Autosizing Reduction

    G'Day everyone,

    I've made a subclass of the QLabel widget which automatically adjusts it's font size depending on the amount of space in it's frame. It expands quite well, and in a single pass can adjust to the correct size. When quickly minimising (ie using it upper right window buttons) to a smaller size, the widget visibly re-adjusts incrementally. I understand why this is happening based on my code. The widget cannot resize smaller than the contents so it much go as small as it can, then the content adjusts, and so on.

    My question, how can I over come this 'slow' adjustment?

    I thought of having the content take a small value when the frame is decreased in size, and then in a second pass could grow to the correct size (after the frame has adjusted). This still seems like a poor approach to me though. I am sure some of you guys must know how this should be handled.

    Here is the code for my subclassed QLabel:

    Qt Code:
    1. MyLabel::MyLabel(QWidget *parent):
    2. QLabel(parent)
    3. {
    4. }
    5.  
    6. void MyLabel::resizeEvent(QResizeEvent *event)
    7. {
    8. // new font size
    9. fontSizeRatio = 0.8;
    10. qreal frameOffset = (1-fontSizeRatio)*0.75;
    11. qreal textHeight = fontMetrics().height();
    12.  
    13. // (if text height is a bit small for the frame height) or (if text is height is a bit too big for frame height)
    14. if(((1+frameOffset)*textHeight < height()) | (textHeight > (1-frameOffset)*height())){
    15. int newFontSize = -1;
    16.  
    17. // if the text width ditates a greater height than the label, use that height, otherwise use the label height
    18. if(heightForWidth(fontMetrics().width(text())) > height())
    19. newFontSize = heightForWidth(fontMetrics().width(text()));
    20. else
    21. newFontSize = height();
    22.  
    23. newFontSize *= fontSizeRatio;
    24.  
    25. QFont newFont = font();
    26. newFont.setPixelSize(newFontSize);
    27. setFont(newFont);
    28. }
    29. }
    To copy to clipboard, switch view to plain text mode 


    Thanks very much for your help, I really appreciate it
    - Cotlone

  2. #2
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QLabel Autosizing Reduction

    I haven't tested, but I wouldn't call setFont(). I guess you can get rid of your problem if you store the calculated font size in a private member, call update() and then reimp paint event where you use the font size yourself. On setText() you once have to calculate the absolute minimum label size (with the minimum font you like) and set that size.

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

    Cotlone (28th December 2011)

  4. #3
    Join Date
    Apr 2010
    Posts
    27
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QLabel Autosizing Reduction

    Thanks for your help Lykurg,

    I'll give it a shot and see how it goes

    -Cotlone

  5. #4
    Join Date
    Apr 2010
    Posts
    27
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QLabel Autosizing Reduction

    Ok, so is this basically making setFont() and font() unusable?
    Would it be best to have an accurate portrayal of the font used in the widget with the font() function? In order to have a more robust solution I mean.

    At any rate, I seem to have a functional auto-sizing QLabel subclass now. I am not sure if this is exactly what you mean, but let me know if you think I should change anything about it.

    Qt Code:
    1. void MyLabel::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4.  
    5. QFont newFont(font());
    6. newFont.setPixelSize(fontSize);
    7. QFontMetrics fm(newFont);
    8.  
    9. int fontHeightForWidth = 0;
    10. if (fm.width(text()))
    11. fontHeightForWidth = width()*fm.height()/fm.width(text());
    12.  
    13. if(fontHeightForWidth < height())
    14. fontSize = fontHeightForWidth;
    15. else
    16. fontSize = height();
    17.  
    18. fontSize *= fontSizeRatio;
    19. newFont.setPixelSize(fontSize);
    20.  
    21. painter.setFont(newFont);
    22. painter.drawText(event->rect(), Qt::AlignCenter, text());
    23. }
    To copy to clipboard, switch view to plain text mode 

    Thanks for your help,
    Cotlone

  6. #5
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QLabel Autosizing Reduction

    that is what I had in mind. Only fontSizeRatio is puzzling me.

  7. #6
    Join Date
    Apr 2010
    Posts
    27
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QLabel Autosizing Reduction

    The fontSizeRatio was a decimal fraction (eg 0.8) used to reduce the size of the text from the edge of its frame by some amount.

    It seems there is a problem in my code now that you point this out. When I set the fontSizeRatio to 1, I would expect the text to meet the width of the frame. It appears too large though. I am not sure why this is the case. I am using width() to find the widget's width.

    I doubt it, but is it something to do with the layouts it is in?

    Cheers,
    Cotlone


    Edit: Actually, I measured the pixel height of the drawn text on the screen to be around 100pixels whilst the setPixelSize(fontSize) function was receiving a value of 64 pixels. In this condition, the text is surpassing the boundary of the widget. What could cause the drawn pixel size to differ from what is specified?
    Last edited by Cotlone; 19th January 2012 at 02:02. Reason: updated contents

  8. #7
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: QLabel Autosizing Reduction

    The pixel size of the font is not the absolute height! See
    Qt Code:
    1. QFont f("Linux Libertine O");
    2. f.setPixelSize(100);
    3. QFontMetrics fm(f);
    4. qWarning() << fm.height() << f.pixelSize();
    To copy to clipboard, switch view to plain text mode 
    Take your calculation as a starting point for a loop where you adjust the size ala
    Qt Code:
    1. QFont f = font();
    2. realfontSize = fontSize;
    3. while(QFontMetrics(f).height() > height())
    4. {f.setPixelSize(realfontSize--);}
    To copy to clipboard, switch view to plain text mode 
    But you should do some optimizations... Or simply scale QPainter to the needed size!

  9. The following user says thank you to Lykurg for this useful post:

    Cotlone (20th January 2012)

  10. #8
    Join Date
    Apr 2010
    Posts
    27
    Thanks
    5
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QLabel Autosizing Reduction

    Ah, right. I didn't realise that. Thanks Lykurg!

    Here is my new code for those who may need it.

    Qt Code:
    1. void MyLabel::paintEvent(QPaintEvent *event)
    2. {
    3. QPainter painter(this);
    4.  
    5. QFont f(font());
    6. f.setPixelSize(fontSize);
    7. QFontMetrics fm(f);
    8.  
    9. int fontHeightForWidth = 0;
    10. if (fm.width(text()))
    11. fontHeightForWidth = width()*fm.height()/fm.width(text());
    12.  
    13. if(fontHeightForWidth < height())
    14. fontSize = fontHeightForWidth;
    15. else
    16. fontSize = height();
    17.  
    18. f.setPixelSize(fontSize);
    19. fontSize = fontSize*f.pixelSize()/QFontMetrics(f).height();
    20. f.setPixelSize(fontSize);
    21.  
    22. painter.setFont(f);
    23. painter.drawText(event->rect(), Qt::AlignCenter, text());
    24. }
    To copy to clipboard, switch view to plain text mode 

    Thanks again mate!

    - Cotlone

Similar Threads

  1. Replies: 1
    Last Post: 29th September 2009, 19:44
  2. Replies: 2
    Last Post: 14th September 2009, 22:30
  3. QLabel bug??? Please help
    By jwieland in forum Qt Programming
    Replies: 3
    Last Post: 3rd April 2009, 20:04
  4. Replies: 1
    Last Post: 2nd August 2008, 15:46
  5. QLabel
    By xapek in forum Qt Programming
    Replies: 1
    Last Post: 19th January 2007, 10:27

Tags for this Thread

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.