Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Automatically Scale Text in QLabels
Forum Updated to NodeBB v4.3 + New Features

Automatically Scale Text in QLabels

Scheduled Pinned Locked Moved General and Desktop
10 Posts 6 Posters 23.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    oracle3001
    wrote on last edited by
    #1

    If I have a set of QLabels in a widget, as I resize the widget I would like the QLabels not only to fill the space available (as any layout will handle), I also want the Label text to scale proportionately.

    How do you go about doing this?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      I would reimplement resizeEvent and update the font size based on the new widget size

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #3

        to add up to SGaist:
        in the resizeEvent use QLabel::contentsRect() and QFontMetrics::boundingRect()

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        0
        • O Offline
          O Offline
          oracle3001
          wrote on last edited by
          #4

          [quote author="raven-worx" date="1388647547"]to add up to SGaist:
          in the resizeEvent use QLabel::contentsRect() and QFontMetrics::boundingRect()[/quote]

          Thanks...could you possibly expand a bit on what you mean by this?

          1 Reply Last reply
          0
          • raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by VRonin
            #5

            something like this:

            void MyLabel::resizeEvent(QResizeEvent* event)
            {
                 QLabel::resizeEvent(event);
            
                 QFont font = this->font();
                 QRect cRect = this->contentsRect();
            
                if( this->text().isEmpty() )
                        return;
            
                 int fontSize = 1;
            
                  while( true )
                  {
                              QFont f(font);
                                   f.setPixelSize( fontSize );
                              QRect r = QFontMetrics(f).boundingRect( this->text() );
                              if (r.height() <= cRect.height() && r.width() <= cRect.widht() )
                                    fontSize++;
                              else
                                    break;
                  }
            
                 font.setPixelSize(fontSize);
                 this->setFont(font);
            }
            

            Not tested though, but it should give you an idea.

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            Z 1 Reply Last reply
            3
            • O Offline
              O Offline
              oracle3001
              wrote on last edited by
              #6

              Thanks, I will give it a try.

              1 Reply Last reply
              0
              • raven-worxR raven-worx

                something like this:

                void MyLabel::resizeEvent(QResizeEvent* event)
                {
                     QLabel::resizeEvent(event);
                
                     QFont font = this->font();
                     QRect cRect = this->contentsRect();
                
                    if( this->text().isEmpty() )
                            return;
                
                     int fontSize = 1;
                
                      while( true )
                      {
                                  QFont f(font);
                                       f.setPixelSize( fontSize );
                                  QRect r = QFontMetrics(f).boundingRect( this->text() );
                                  if (r.height() <= cRect.height() && r.width() <= cRect.widht() )
                                        fontSize++;
                                  else
                                        break;
                      }
                
                     font.setPixelSize(fontSize);
                     this->setFont(font);
                }
                

                Not tested though, but it should give you an idea.

                Z Offline
                Z Offline
                zed962
                wrote on last edited by
                #7

                @raven-worx This method is too slow...

                A 1 Reply Last reply
                0
                • Z zed962

                  @raven-worx This method is too slow...

                  A Offline
                  A Offline
                  ambershark
                  wrote on last edited by
                  #8

                  @zed962 Yea I doubt he meant it for production level code without optimizations. It was meant to give the guy an idea on how to deal with it.

                  If you wanted to use it in production you would need to limit the calling of the while loop during the resize event. I would call that only after the person had chosen a size, or maybe less often during the resizing. Or finally, use a member or static var and track sizes and only recalculate sizing as things don't fit.

                  Don't forget most of us that answer questions on these forums pull the code right out of our heads as an example for people to base their fixes off. The code is rarely ready to be dropped into a project. But we all assume the developers asking the questions can figure out things like compiler errors (again code type from our heads) and optimizations themselves. :)

                  My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                  Z 1 Reply Last reply
                  6
                  • A ambershark

                    @zed962 Yea I doubt he meant it for production level code without optimizations. It was meant to give the guy an idea on how to deal with it.

                    If you wanted to use it in production you would need to limit the calling of the while loop during the resize event. I would call that only after the person had chosen a size, or maybe less often during the resizing. Or finally, use a member or static var and track sizes and only recalculate sizing as things don't fit.

                    Don't forget most of us that answer questions on these forums pull the code right out of our heads as an example for people to base their fixes off. The code is rarely ready to be dropped into a project. But we all assume the developers asking the questions can figure out things like compiler errors (again code type from our heads) and optimizations themselves. :)

                    Z Offline
                    Z Offline
                    zed962
                    wrote on last edited by
                    #9

                    @ambershark sure thing and I appreciate the time everyone is taking to come up with solutions. Thanks for your solution ^^.

                    1 Reply Last reply
                    1
                    • VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by VRonin
                      #10

                      you should use something like:

                      #include <QLabel>
                      #include <QTimer>
                      class ScaleTextlabel : public QLabel{
                          Q_OBJECT
                          Q_DISABLE_COPY(ScaleTextlabel)
                      public:
                          explicit ScaleTextlabel(QWidget* parent=Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags())
                              :QLabel(parent,f)
                          {
                             initTimer();
                          }
                          explicit ScaleTextlabel(const QString &text, QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags())
                              :QLabel(text,parent,f)
                          {
                             initTimer();
                          }
                      
                      protected:
                          void resizeEvent(QResizeEvent* event) override{
                              QLabel::resizeEvent(event);
                              m_resizeTimer->start();
                          }
                      protected slots:
                          void resizeFont(){
                              QFont basefont = font();
                              const QRect baseRect = contentsRect();
                              const QString baseText = text();
                              int fontSizeGuess = qMax(1,basefont.pixelSize());
                              for(;;++fontSizeGuess){
                                  QFont testFont(basefont);
                                  testFont.setPixelSize(fontSizeGuess);
                                  const QRect fontRect=QFontMetrics(testFont).boundingRect(baseText);
                                  if(fontRect.height()>baseRect.height() || fontRect.width()>baseRect.width())
                                      break;
                              }
                              for(;fontSizeGuess>1;--fontSizeGuess){
                                  QFont testFont(basefont);
                                  testFont.setPixelSize(fontSizeGuess);
                                  const QRect fontRect=QFontMetrics(testFont).boundingRect(baseText);
                                  if(fontRect.height()<=baseRect.height() && fontRect.width()<=baseRect.width())
                                      break;
                              }
                              basefont.setPixelSize(fontSizeGuess);
                              setFont(basefont);
                          }
                      
                      private:
                          void initTimer(){
                              m_resizeTimer=new QTimer(this);
                              m_resizeTimer->setInterval(100);
                              m_resizeTimer->setSingleShot(true);
                              connect(m_resizeTimer,&QTimer::timeout,this,&ScaleTextlabel::resizeFont);
                          }
                      
                          QTimer* m_resizeTimer;
                      };
                      
                      

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      1 Reply Last reply
                      2

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved