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. Controlling the size of a QScrollArea

Controlling the size of a QScrollArea

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 2 Posters 5.6k 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.
  • C Offline
    C Offline
    ChainReaction
    wrote on last edited by ChainReaction
    #1

    Hey.
    Consider the following:
    0_1551297190986_6fd3253b-1cb0-4a1b-9659-0e7704be9b7f-image.png
    Where Widget C is a parent of Widget A & Widget B and installed with QVBoxLayout, and all are subclasses of QWidget.

    Now, I want Widget B to take more space in height, but not on the expense of Widget A.
    Something along the line of:
    0_1551297235108_ffe937db-65d2-4125-8819-d471f1957fc8-image.png

    I tried re-implementing Widget B's QSize sizeHint()const:

    QSize WidgetB::sizeHint()const {
        QSize parentSize(QWidget::sizeHint());
        return QSize(parentSize.width(), parentSize.height() + 500);
    }
    

    Unfortunately, this had no effect.

    On the other hand, re-implementing QSize minimumSizeHint()const did the trick:

    QSize WidgetB::minimumSizeHint()const {
        QSize parentSize(QWidget::minimumSizeHint());
        return QSize(parentSize.width(), parentSize.height() + 500);
    }
    

    But this is not a good solution for me, since I cannot resize Widget C (top level widget) because of Widget B minimum requirement.

    I want Widget B's size to start off with extended height, and let the user choose if they want to reduce Widget B height by resizing Widget C (which is the top level window).

    So; why is QSize sizeHint()const being ignored by Widget C's QVBoxLayout?
    How can I achieve the desired effect?

    Thanks.

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

      Hi,

      Why not use the stretch parameter when calling addWidget ?

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

      C 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        Why not use the stretch parameter when calling addWidget ?

        C Offline
        C Offline
        ChainReaction
        wrote on last edited by
        #3

        @SGaist ok, I tried using stretch but this had no effect...

            QVBoxLayout *mainLayout = new QVBoxLayout;
            mainLayout->addWidget(_mainPanel);
            mainLayout->addWidget(_bottomPanel, 2);
            setLayout(mainLayout);
        

        could it be related to some of the properties of _mainPanel (aka "Widget A") and _bottomPanel (aka "Widget B")?
        what am I missing here?

        Thanks.

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

          Did you keep your sizeHint overloads ?

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

          C 1 Reply Last reply
          0
          • SGaistS SGaist

            Did you keep your sizeHint overloads ?

            C Offline
            C Offline
            ChainReaction
            wrote on last edited by ChainReaction
            #5

            @SGaist OK! Progress! :)
            Indeed, I had to keep the overload for the sizeHint() and so I did, and now

            QVBoxLayout *mainLayout = new QVBoxLayout;
                mainLayout->addWidget(_mainPanel);
                mainLayout->addWidget(_bottomPanel, 2);
                setLayout(mainLayout);
            

            Together with this in _bottomPanel:

            QSize BottomPanel::sizeHint()const {
                QSize parentSize(QWidget::sizeHint());
                return QSize(parentSize.width(), parentSize.height() + 500);
            }
            

            Caused BottomPanel to be higher, but not by as much as I'd like.
            So I tried increasing:

            mainLayout->addWidget(_bottomPanel, 4); // now it's 4
            

            and:

            QSize BottomPanel::sizeHint()const {
                QSize parentSize(QWidget::sizeHint());
                return QSize(parentSize.width(), parentSize.height() + 800); // now it's 800
            }
            

            and it didn't grew further.
            Can you please explain how exactly does the factor works?
            The doc doesn't say much:

            The stretch factor applies only in the direction of the QBoxLayout, and is relative to the other boxes and widgets in this QBoxLayout. Widgets and boxes with higher stretch factors grow more.

            If the stretch factor is 0 and nothing else in the QBoxLayout has a stretch factor greater than zero, the space is distributed according to the QWidget:sizePolicy() of each widget that's involved.

            Nothing about the need to also re-implement sizeHint()...

            Thanks!

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

              The thing is, you are putting your widgets in a QScrollArea. So depending on how you did configure things, the growth of your widgets might be impacted.

              You should first get your widgets working as you want without the scroll area and then add it back to the mix.

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

              C 1 Reply Last reply
              0
              • SGaistS SGaist

                The thing is, you are putting your widgets in a QScrollArea. So depending on how you did configure things, the growth of your widgets might be impacted.

                You should first get your widgets working as you want without the scroll area and then add it back to the mix.

                C Offline
                C Offline
                ChainReaction
                wrote on last edited by
                #7

                @SGaist sorry, my bad.
                I should have mentioned (I was sure I did but apparently didn't), that in the pictures above, WidgetB is a subcalss of QScrollArea, not WidgetC.
                Why does the layout care which QWidget is it?

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

                  QScrollArea is not used like that. You should your widgets in a "container" QWidget that you give to QScrollArea using setWidget.

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

                  C 1 Reply Last reply
                  1
                  • SGaistS SGaist

                    QScrollArea is not used like that. You should your widgets in a "container" QWidget that you give to QScrollArea using setWidget.

                    C Offline
                    C Offline
                    ChainReaction
                    wrote on last edited by ChainReaction
                    #9

                    @SGaist thanks for the consultant. Appreciate it.

                    Let me please start over, I will be more specific.

                    So what I currently have is this:

                    0_1551429827541_fd897439-cf06-47c2-91cb-5c48247b090b-image.png

                    QWidgetBlack installed QVBoxLayout and added two widgets: QWidgetRedTop and QWidgetRedBottom.
                    QWidgetRedBottom installed QVBoxLayout and added QScrollAreaBlue
                    QScrollAreaBlue added QWidgetGreen using QScrollAreaBlue::setWidget(QWidgetGreen) (this here)

                    Now, what I want is the app to start like this:

                    0_1551430438217_5255f0eb-6b38-4a5f-aefc-4c053c36d890-image.png

                    So, following your first advice, I did:
                    On QWidgetBlack:

                    QVboxLayout* vbox = new QVBoxLayout;
                    vbox->addWidget(QWidgetRedTop); 
                    vbox->addWidget(QWidgetRedBottom, 1); // with stretch
                    

                    On QWidgetRedBottom:

                    QSize QWidgetRedBottom::sizeHint()const { // override
                        QSize s = QWidget::sizeHint();
                        return QSize(s.width(), s.height() + 600);
                    }
                    

                    And indeed it stretched out the way I wanted, but not enough.
                    increasing both:

                    vbox->addWidget(QWidgetRedBottom, 2); // with bigger stretch
                    

                    and

                    QSize QWidgetRedBottom::sizeHint()const { // override
                        QSize s = QWidget::sizeHint();
                        return QSize(s.width(), s.height() + 800); // now 800 instead of 600
                    }
                    

                    did not make it grow any further.

                    Why is that? What am I doing wrong?

                    Thanks.

                    C 1 Reply Last reply
                    0
                    • C ChainReaction

                      @SGaist thanks for the consultant. Appreciate it.

                      Let me please start over, I will be more specific.

                      So what I currently have is this:

                      0_1551429827541_fd897439-cf06-47c2-91cb-5c48247b090b-image.png

                      QWidgetBlack installed QVBoxLayout and added two widgets: QWidgetRedTop and QWidgetRedBottom.
                      QWidgetRedBottom installed QVBoxLayout and added QScrollAreaBlue
                      QScrollAreaBlue added QWidgetGreen using QScrollAreaBlue::setWidget(QWidgetGreen) (this here)

                      Now, what I want is the app to start like this:

                      0_1551430438217_5255f0eb-6b38-4a5f-aefc-4c053c36d890-image.png

                      So, following your first advice, I did:
                      On QWidgetBlack:

                      QVboxLayout* vbox = new QVBoxLayout;
                      vbox->addWidget(QWidgetRedTop); 
                      vbox->addWidget(QWidgetRedBottom, 1); // with stretch
                      

                      On QWidgetRedBottom:

                      QSize QWidgetRedBottom::sizeHint()const { // override
                          QSize s = QWidget::sizeHint();
                          return QSize(s.width(), s.height() + 600);
                      }
                      

                      And indeed it stretched out the way I wanted, but not enough.
                      increasing both:

                      vbox->addWidget(QWidgetRedBottom, 2); // with bigger stretch
                      

                      and

                      QSize QWidgetRedBottom::sizeHint()const { // override
                          QSize s = QWidget::sizeHint();
                          return QSize(s.width(), s.height() + 800); // now 800 instead of 600
                      }
                      

                      did not make it grow any further.

                      Why is that? What am I doing wrong?

                      Thanks.

                      C Offline
                      C Offline
                      ChainReaction
                      wrote on last edited by ChainReaction
                      #10

                      I think I found a similar question here, that also solves my predicament.

                      Quoting from there, the relevant part is:

                      So the most you can do is to define sizeHint and minimumSizeHint, set a stretch factor greater than all the others, and set a size-policy of Expanding. But even with all these things in place, it seems the layout manager is still not guaranteed to honour the size-hint when the minimum-size-hint is less.
                      The problem is that the definition of Expanding is not quite strong enough:

                      The sizeHint() is a sensible size, but the widget can be shrunk and still be useful. The widget can make use of extra space, so it should get as much space as possible (e.g. the horizontal direction of a horizontal slider).

                      For whatever reason, the layout manager seems to prioritise shrinking over expanding if another widget has a stronger size-policy (e.g. Fixed). This looks like the wrong choice from the point of view of your example, but I suppose there may be other situations where it makes more sense. The behaviour seems to be exactly the same in both Qt4 and Qt5, so I don't know whether it should be considered a bug, or just a quirk of the implementation.

                      So I used the same workaround:
                      In QWidgetBlack:

                      QVboxLayout* vbox = new QVBoxLayout;
                      vbox->addWidget(QWidgetRedTop); 
                      vbox->addWidget(QWidgetRedBottom); // no need for stretch...
                      setLayout(vbox);
                      
                      /* WA */
                      QWidgetRedBottom->setMinimumSize(QWidgetRedBottom->sizeHint());
                      adjustSize();
                      QWidgetRedBottom->setMinimumSize(QWidgetRedBottom->minimumSizeHint());
                      /******/
                      

                      and it totally worked!

                      If anyone has comments/suggestions for a different solution I'd be happy to learn.

                      1 Reply Last reply
                      0

                      • Login

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