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. How to make a QScrollArea resize to fit its contents?
Forum Updated to NodeBB v4.3 + New Features

How to make a QScrollArea resize to fit its contents?

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 876 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.
  • L Offline
    L Offline
    Laila
    wrote on last edited by Laila
    #1

    How i could make a QScrollArea stick on the top and grow according to the widgets added to it?

    When I add the QScrollArea to the layout as vlayout->addWidget(scrollArea, 0, Qt::AlignTop);

    it doesn't obey the Qt::AlignTop flag and is floating on the middle:

    pic1.png

    class Widget : public QWidget  // source: Qt6
    {
        Q_OBJECT
    public:
    
        Widget() : QWidget(nullptr)
        {
            QVBoxLayout* vlayout = new QVBoxLayout(this);
    
            QScrollArea* scrollArea       = new ScrollArea(this);
            QWidget* scrollAreaWidget     = new QWidget(scrollArea);
            QVBoxLayout* scrollAreaLayout = new QVBoxLayout(scrollAreaWidget);
            scrollAreaLayout->setContentsMargins(0, 0, 0, 0);
            scrollAreaLayout->setSizeConstraint(QLayout::SetFixedSize);
            scrollAreaWidget->setLayout(scrollAreaLayout);
            scrollArea->setWidget(scrollAreaWidget);
            scrollArea->setWidgetResizable(true);
            scrollArea->setAlignment(Qt::AlignTop);
            scrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
            //scrollArea->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    
            QPushButton* add = new QPushButton("add", this);
            connect(add, &QPushButton::clicked, [=]
    		{
                QWidget* widget = new QWidget;
                QHBoxLayout* hlayout = new QHBoxLayout(widget);
                hlayout->setContentsMargins(0, 0, 0, 0);
    			QPushButton* button  = new QPushButton("button_" + QString::number(scrollAreaLayout->count()), this);
                button->setFixedWidth(300);
                QPushButton* remove  = new QPushButton("remove", this);
                hlayout->addWidget(button);
                hlayout->addWidget(remove);
                connect(remove, &QPushButton::clicked, [=]{	widget->deleteLater(); });
                scrollAreaLayout->addWidget(widget, 0, Qt::AlignTop);
    		});
    
            vlayout->addWidget(add, 0, Qt::AlignTop);
            //vlayout->addWidget(scrollArea);
            vlayout->addWidget(scrollArea, 0, Qt::AlignTop);
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget widget;
        widget.show();
    }
    

    When i add it to the layout as vlayout->addWidget(scrollArea); it grows to the entire layout height:

    pic2.png

    I have tried all size policies scrollArea->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); and also:

    scrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
    

    On the documentation it says:

    QAbstractScrollArea::AdjustToContents
    The scroll area will always adjust to the viewport

    Why is it not adjusting? I'm doing something wrong?
    What i'm trying to achieve is to have it on the top and make it grow according to the widgets added to it.

    It would look like this:

    pic3.png

    Then it would continue growing for each widget added until there's no more space on the parent layout, and at this point it would then display the QScrollBars.

    M 1 Reply Last reply
    0
    • hskoglundH Offline
      hskoglundH Offline
      hskoglund
      wrote on last edited by
      #2

      Hi, it look like you have too many QVBoxLayouts up and running, and probably you're doing the setAlignment(Qt::AlignTop); on the wrong one (the lowest in the hierarchy).

      Try doing the allignment setting on the top/outer QVBoxLayout, say like this:

      ...
      Widget() : QWidget(nullptr)
          {
              QVBoxLayout* vlayout = new QVBoxLayout(this);
              vlayout->setAlignment(Qt::AlignTop);
      ...
      
      1 Reply Last reply
      0
      • L Offline
        L Offline
        Laila
        wrote on last edited by Laila
        #3

        Now the QScrollArea stick on top but if i set:

        scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
        

        It doesn't grow when new widgets are added to it, and if i set:

        scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        

        It grows to the entire layout height which is not what im trying to achieve.

        1 Reply Last reply
        0
        • L Laila

          How i could make a QScrollArea stick on the top and grow according to the widgets added to it?

          When I add the QScrollArea to the layout as vlayout->addWidget(scrollArea, 0, Qt::AlignTop);

          it doesn't obey the Qt::AlignTop flag and is floating on the middle:

          pic1.png

          class Widget : public QWidget  // source: Qt6
          {
              Q_OBJECT
          public:
          
              Widget() : QWidget(nullptr)
              {
                  QVBoxLayout* vlayout = new QVBoxLayout(this);
          
                  QScrollArea* scrollArea       = new ScrollArea(this);
                  QWidget* scrollAreaWidget     = new QWidget(scrollArea);
                  QVBoxLayout* scrollAreaLayout = new QVBoxLayout(scrollAreaWidget);
                  scrollAreaLayout->setContentsMargins(0, 0, 0, 0);
                  scrollAreaLayout->setSizeConstraint(QLayout::SetFixedSize);
                  scrollAreaWidget->setLayout(scrollAreaLayout);
                  scrollArea->setWidget(scrollAreaWidget);
                  scrollArea->setWidgetResizable(true);
                  scrollArea->setAlignment(Qt::AlignTop);
                  scrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
                  //scrollArea->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
          
                  QPushButton* add = new QPushButton("add", this);
                  connect(add, &QPushButton::clicked, [=]
          		{
                      QWidget* widget = new QWidget;
                      QHBoxLayout* hlayout = new QHBoxLayout(widget);
                      hlayout->setContentsMargins(0, 0, 0, 0);
          			QPushButton* button  = new QPushButton("button_" + QString::number(scrollAreaLayout->count()), this);
                      button->setFixedWidth(300);
                      QPushButton* remove  = new QPushButton("remove", this);
                      hlayout->addWidget(button);
                      hlayout->addWidget(remove);
                      connect(remove, &QPushButton::clicked, [=]{	widget->deleteLater(); });
                      scrollAreaLayout->addWidget(widget, 0, Qt::AlignTop);
          		});
          
                  vlayout->addWidget(add, 0, Qt::AlignTop);
                  //vlayout->addWidget(scrollArea);
                  vlayout->addWidget(scrollArea, 0, Qt::AlignTop);
              }
          };
          
          int main(int argc, char *argv[])
          {
              QApplication a(argc, argv);
              Widget widget;
              widget.show();
          }
          

          When i add it to the layout as vlayout->addWidget(scrollArea); it grows to the entire layout height:

          pic2.png

          I have tried all size policies scrollArea->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); and also:

          scrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
          

          On the documentation it says:

          QAbstractScrollArea::AdjustToContents
          The scroll area will always adjust to the viewport

          Why is it not adjusting? I'm doing something wrong?
          What i'm trying to achieve is to have it on the top and make it grow according to the widgets added to it.

          It would look like this:

          pic3.png

          Then it would continue growing for each widget added until there's no more space on the parent layout, and at this point it would then display the QScrollBars.

          M Offline
          M Offline
          mpergand
          wrote on last edited by
          #4

          @Laila
          I don't think it is possible.

          However your code is confused.

          Widget() : QWidget(nullptr)
          	{
          		QVBoxLayout* vlayout = new QVBoxLayout(this);
          		QPushButton* add = new QPushButton("add");
          		QScrollArea* scrollArea	= new QScrollArea;
          		vlayout->addWidget(add);
          		vlayout->addWidget(scrollArea);
          
          		QWidget* scrollAreaWidget     = new QWidget;
          		QVBoxLayout* scrollAreaLayout = new QVBoxLayout(scrollAreaWidget);
          		scrollAreaLayout->setContentsMargins(0, 0, 0, 0);
          		//scrollAreaLayout->setSizeConstraint(QLayout::SetFixedSize);
          		scrollAreaWidget->setLayout(scrollAreaLayout);
          		scrollArea->setWidget(scrollAreaWidget);
          		scrollArea->setWidgetResizable(true);
          		scrollArea->setAlignment(Qt::AlignTop);
          		//scrollArea->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
          		//scrollArea->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
          
          		connect(add, &QPushButton::clicked, [=]
          		{
          			QWidget* widget = new QWidget;
          			QHBoxLayout* hlayout = new QHBoxLayout(widget);
          			hlayout->setContentsMargins(0, 0, 0, 0);
          			QPushButton* button  = new QPushButton("button_" + QString::number(scrollAreaLayout->count()), this);
          			button->setFixedWidth(300);
          			QPushButton* remove  = new QPushButton("remove", this);
          			hlayout->addWidget(button);
          			hlayout->addWidget(remove);
          			connect(remove, &QPushButton::clicked, [=]{	widget->deleteLater(); });
          			scrollAreaLayout->addWidget(widget, 0, Qt::AlignTop);
          		});
          
          //		vlayout->addWidget(add, 0, Qt::AlignTop);
          //		//vlayout->addWidget(scrollArea);
          //		vlayout->addWidget(scrollArea, 0, Qt::AlignTop);
          	}
          
          1 Reply Last reply
          0
          • L Offline
            L Offline
            Laila
            wrote on last edited by
            #5

            If its not possible, then whats the point of QAbstractScrollArea::AdjustToContents?

            1 Reply Last reply
            0
            • hskoglundH Offline
              hskoglundH Offline
              hskoglund
              wrote on last edited by
              #6

              QAbstractScrollArea::AdjustToContents() I think works fine, the problem I think is that nothing currently resizes the scrollArea (inside the QVBoxLayout). Once it resized the QAbstractScrollArea::AdjustToContents() will work.

              The horizontal resizing is done courtesy of the QVBoxLayout so you only need to take care of the vertical resizing, once simple (stupid :-) would be to do the resizing via the resizeEvent, say you add this code after Widget's constructor:

              ...
              void resizeEvent(QResizeEvent* event)
              {
                  scrollArea->setMinimumHeight(height() - 60);   // 60 or maybe something bigger to avoid endless resizing
              }
              

              Also you need to move the variable declaration for the scrollArea outside of the constructor (so it can be reached from the resize event) say change like this:

              public:
                  QScrollArea* scrollArea;
                  
                  Widget() : QWidget(nullptr)
                  {
                      QVBoxLayout* vlayout = new QVBoxLayout(this);
                      
                      scrollArea                    = new ScrollArea(this);
                      QWidget* scrollAreaWidget     = new QWidget(scrollArea);
              ...
              
              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