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. The size of window will increase when a QLabel use setPixmap() in QTabWidget

The size of window will increase when a QLabel use setPixmap() in QTabWidget

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtabwidgetqlabelsetpixmapbugqlayout
7 Posts 3 Posters 454 Views
  • 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.
  • H Offline
    H Offline
    herocon
    wrote on 20 Aug 2024, 01:14 last edited by
    #1

    ac927847-d35c-408b-9ff0-55bd0947f619-image.png
    I use Qt5.15.2 in win11 and ubuntu20.04.
    The Widget uses a layout, and the tabWidget also uses a layout. When the label uses the setPixmap(pix) function, and the size of pix is equal with the size of the label,the Widget will become bigger. When the width of pix's size is less than the width of the label's size minus 6, and the height of pix's size is less than the height of the label's size minus 6, everything works normally.

    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    
    QT_BEGIN_NAMESPACE
    namespace Ui {
    class Widget;
    }
    QT_END_NAMESPACE
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    
    protected:
        void timerEvent(QTimerEvent *e);
        void resizeEvent(QResizeEvent *e);
    
    private:
        Ui::Widget *ui;
    };
    #endif // WIDGET_H
    

    widget.cpp

    #include "widget.h"
    #include "ui_widget.h"
    #include <QDebug>
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::Widget)
    {
        ui->setupUi(this);
        startTimer(1000);
        qDebug() << this->geometry();
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::timerEvent(QTimerEvent *e)
    {
        qDebug() << ui->label->geometry();
        QPixmap p("/home/li/Pictures/1.jpg");
        ui->label->setPixmap(p.scaled(ui->label->size()));
    }
    
    void Widget::resizeEvent(QResizeEvent *e)
    {
        qDebug() << "resizeEvent" <<ui->label->geometry();
    }
    
    P 1 Reply Last reply 20 Aug 2024, 12:40
    0
    • H Offline
      H Offline
      herocon
      wrote on 20 Aug 2024, 01:33 last edited by
      #2

      If QStackedWidget is used in place of QTabWidget, this bug does not occur.

      J 1 Reply Last reply 20 Aug 2024, 06:46
      0
      • H herocon
        20 Aug 2024, 01:33

        If QStackedWidget is used in place of QTabWidget, this bug does not occur.

        J Offline
        J Offline
        JonB
        wrote on 20 Aug 2024, 06:46 last edited by JonB
        #3

        @herocon
        Various widgets have things like content margins. Have you looked to see whether that is the difference?

        H 1 Reply Last reply 20 Aug 2024, 08:48
        0
        • J JonB
          20 Aug 2024, 06:46

          @herocon
          Various widgets have things like content margins. Have you looked to see whether that is the difference?

          H Offline
          H Offline
          herocon
          wrote on 20 Aug 2024, 08:48 last edited by
          #4

          @JonB said in The size of window will increase when a QLabel use setPixmap() in QTabWidget:

          @herocon
          Various widgets have things like content margins. Have you looked to see whether that is the difference?

          QTabWidget is implemented based on QStackedWidget, but QStackedWidget does not have this bug. I suspect that the bug is caused by QTabWidget, or it could be that setPixmap() triggers a resize() of the QLayout.
          The default content margins of QWidget is (0,0,0,0). The default content margins of QGridLayout is (11,11,11,11), but which shown in QtDesigner is (9,9,9,9).It may be another bug.Though there are various properties, the properties should not change the widget's size.

          1 Reply Last reply
          0
          • H herocon
            20 Aug 2024, 01:14

            ac927847-d35c-408b-9ff0-55bd0947f619-image.png
            I use Qt5.15.2 in win11 and ubuntu20.04.
            The Widget uses a layout, and the tabWidget also uses a layout. When the label uses the setPixmap(pix) function, and the size of pix is equal with the size of the label,the Widget will become bigger. When the width of pix's size is less than the width of the label's size minus 6, and the height of pix's size is less than the height of the label's size minus 6, everything works normally.

            widget.h

            #ifndef WIDGET_H
            #define WIDGET_H
            
            #include <QWidget>
            
            QT_BEGIN_NAMESPACE
            namespace Ui {
            class Widget;
            }
            QT_END_NAMESPACE
            
            class Widget : public QWidget
            {
                Q_OBJECT
            
            public:
                Widget(QWidget *parent = nullptr);
                ~Widget();
            
            protected:
                void timerEvent(QTimerEvent *e);
                void resizeEvent(QResizeEvent *e);
            
            private:
                Ui::Widget *ui;
            };
            #endif // WIDGET_H
            

            widget.cpp

            #include "widget.h"
            #include "ui_widget.h"
            #include <QDebug>
            
            Widget::Widget(QWidget *parent)
                : QWidget(parent)
                , ui(new Ui::Widget)
            {
                ui->setupUi(this);
                startTimer(1000);
                qDebug() << this->geometry();
            }
            
            Widget::~Widget()
            {
                delete ui;
            }
            
            void Widget::timerEvent(QTimerEvent *e)
            {
                qDebug() << ui->label->geometry();
                QPixmap p("/home/li/Pictures/1.jpg");
                ui->label->setPixmap(p.scaled(ui->label->size()));
            }
            
            void Widget::resizeEvent(QResizeEvent *e)
            {
                qDebug() << "resizeEvent" <<ui->label->geometry();
            }
            
            P Offline
            P Offline
            Pl45m4
            wrote on 20 Aug 2024, 12:40 last edited by Pl45m4
            #5

            @herocon

            Your issue as you describe it sounds odd at first, but after looking at your code, I think I know what's going on:

            If your idea of a bug originates from these two (or three) outputs:

            [ 1 ]

            Widget::Widget(QWidget *parent)
               : QWidget(parent)
               , ui(new Ui::Widget)
            {
               qDebug() << this->geometry();
            }
            

            [ 2 ]

            void Widget::timerEvent(QTimerEvent *e)
            {
               qDebug() << ui->label->geometry();
            }
            

            [ 3 ]

            void Widget::resizeEvent(QResizeEvent *e)
            {
                qDebug() << "resizeEvent" << ui->label->geometry();
            }
            

            then there is no bug.

            You cannot compare the geometry you retrieve within the widget's c'tor with the one after the widget is shown and layouts and other settings apply.

            It might be different for a child widget with no content (QStackedWidget with no "pages"), since it doesn't need to expand that much... but for your Widget:
            It keeps its inital size until it's shown and the resize happens (layouts apply... label child expands with pixmap)...
            So the output you get from [ 1 ] will always be different from [ 2 ] and [ 3 ].

            Implement the Widget::showEvent handler and put your "first test" [ 1 ] there. Then compare again.

            TLDR:
            Don't trust anything (screen) size related that you call from some widget's constructor. It will never be the size of the widget you see on your screen.


            If debugging is the process of removing software bugs, then programming must be the process of putting them in.

            ~E. W. Dijkstra

            H 1 Reply Last reply 21 Aug 2024, 02:05
            1
            • P Pl45m4
              20 Aug 2024, 12:40

              @herocon

              Your issue as you describe it sounds odd at first, but after looking at your code, I think I know what's going on:

              If your idea of a bug originates from these two (or three) outputs:

              [ 1 ]

              Widget::Widget(QWidget *parent)
                 : QWidget(parent)
                 , ui(new Ui::Widget)
              {
                 qDebug() << this->geometry();
              }
              

              [ 2 ]

              void Widget::timerEvent(QTimerEvent *e)
              {
                 qDebug() << ui->label->geometry();
              }
              

              [ 3 ]

              void Widget::resizeEvent(QResizeEvent *e)
              {
                  qDebug() << "resizeEvent" << ui->label->geometry();
              }
              

              then there is no bug.

              You cannot compare the geometry you retrieve within the widget's c'tor with the one after the widget is shown and layouts and other settings apply.

              It might be different for a child widget with no content (QStackedWidget with no "pages"), since it doesn't need to expand that much... but for your Widget:
              It keeps its inital size until it's shown and the resize happens (layouts apply... label child expands with pixmap)...
              So the output you get from [ 1 ] will always be different from [ 2 ] and [ 3 ].

              Implement the Widget::showEvent handler and put your "first test" [ 1 ] there. Then compare again.

              TLDR:
              Don't trust anything (screen) size related that you call from some widget's constructor. It will never be the size of the widget you see on your screen.

              H Offline
              H Offline
              herocon
              wrote on 21 Aug 2024, 02:05 last edited by
              #6

              @Pl45m4 Sorry,I don't show the actual result of my code.The problem is not the information from debug().Actually, the application is getting higher every second in screen.It's not true.It changes the size of application which is parent of the layout.When I use the QStackedWidget and the stackedWidget alse has two pages and a label and layout, application remains unchanged, no matter how many times the timerEvent() occurs.
              startTimer(100); And the result:alt text

              P 1 Reply Last reply 21 Aug 2024, 04:07
              0
              • H herocon
                21 Aug 2024, 02:05

                @Pl45m4 Sorry,I don't show the actual result of my code.The problem is not the information from debug().Actually, the application is getting higher every second in screen.It's not true.It changes the size of application which is parent of the layout.When I use the QStackedWidget and the stackedWidget alse has two pages and a label and layout, application remains unchanged, no matter how many times the timerEvent() occurs.
                startTimer(100); And the result:alt text

                P Offline
                P Offline
                Pl45m4
                wrote on 21 Aug 2024, 04:07 last edited by Pl45m4
                #7

                @herocon

                Ok next attempt:

                ui->label->setPixmap(p.scaled(ui->label->size()));
                

                Each iteration scales the pixmap to current label size and then sets the pixmap to the label.
                By doing this, the size of the label increases with the pixmap (because of border/frame... IIRC 1px per side by default, so 2px in total).
                Then you take the new label size again in the next iteration and apply this new (by 2px) increased size to the pixmap... the label gets the pixmap, grows by about 2px in height and there you have your loop where your label and consequently the whole widget grows ;-)

                So still no bug :)
                And it's exactly the behavior you would expect from the debug output.
                (The height increases by 2 each timer interval).
                When using another layout setup, the layout/other widgets might "buffer" that, so the main app window does not grow.
                But even there, the label itself should definitely grow when you periodically set content which has the exact same size as the outter boundings of the label.
                Why though?!

                Try (not tested):

                int w = ui->label->width();
                int h = ui->label->height();
                ui->label->setPixmap(p.scaled(w - 2, h - 2));
                // or this and set the pixmap only once
                ui->label->setScaledContents(true);
                

                Because a label with w=500, h=500 for example, can't display a pixmap with w=500, h=500. If you set a pixmap with the same size as the label itself, it will start to grow.


                If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                ~E. W. Dijkstra

                1 Reply Last reply
                0

                6/7

                21 Aug 2024, 02:05

                • Login

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