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. Resizing QScrollArea issue
Forum Updated to NodeBB v4.3 + New Features

Resizing QScrollArea issue

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 4 Posters 6.6k Views 1 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.
  • M Offline
    M Offline
    Mattia
    wrote on last edited by
    #1

    Dear all,
    I have to create a scroll area with only the vertical scrolling bar, so I need the width fits exactly the content.
    I have created this example with QtCreator:

    QtCreator.png

    To fit the QScrollArea to the content, I add this code:

    ui.scrollArea->setFixedWidth(ui.scrollAreaWidgetContents->minimumSizeHint().width());
    

    But this does not produce the wanted result:

    GUI.png

    I have noticed that the problem in this example can be solved setting the QWidget of the scroll area as horizontal layout and removing the nested horizontal layout. The problem is that in my project I will have many widgets inside the scroll area, so I can't avoid to set it as vertical layout and to put inside many horizontal layouts and/or tabs.

    How should I solve this problem?

    jsulmJ 1 Reply Last reply
    0
    • M Mattia

      @Bonnie Thanks.
      Let me know if you find a solution can work around this issue!

      B Offline
      B Offline
      Bonnie
      wrote on last edited by Bonnie
      #14

      @Mattia Hi, I think I kind of find a solution.

      1. (in cpp) Remove that setFixedWidth code.
      2. (in ui) Set horizontal size policy of scrollArea to "Fixed" as I mentioned.
      3. (in ui) Reset minimumSize of centralWidget to default (0 x 0)
      4. (in ui) Promote scrollArea to new class: ModScrollArea

      modscrollarea.h

      #ifndef MODSCROLLAREA_H
      #define MODSCROLLAREA_H
      
      #include <QScrollArea>
      
      class ModScrollArea : public QScrollArea
      {
          Q_OBJECT
      public:
          explicit ModScrollArea(QWidget *parent = nullptr);
          QSize sizeHint() const;
      protected:
          bool event(QEvent *e);
      private:
          mutable QSize widgetSize;
      };
      
      #endif // MODSCROLLAREA_H
      

      modscrollarea.cpp

      #include "modscrollarea.h"
      
      #include <QEvent>
      #include <QScrollBar>
      
      ModScrollArea::ModScrollArea(QWidget *parent) : QScrollArea(parent)
      {
      }
      
      QSize ModScrollArea::sizeHint() const
      {
          int f = 2 * frameWidth();
          QSize sz(f, f);
          int h = fontMetrics().height();
          if (widget()) {
              if(!widgetSize.isValid())
                  widgetSize = widgetResizable() ? widget()->sizeHint() : widget()->size();
              sz += widgetSize;
          } else {
              sz += QSize(12 * h, 8 * h);
          }
          if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOn)
              sz.setWidth(sz.width() + verticalScrollBar()->sizeHint().width());
          if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn)
              sz.setHeight(sz.height() + horizontalScrollBar()->sizeHint().height());
          return sz.boundedTo(QSize(sz.width(), 24 * h));
      }
      
      bool ModScrollArea::event(QEvent *e)
      {
          if(e->type() == QEvent::LayoutRequest && widget()) {
              QSize newSize = widgetResizable() ? widget()->sizeHint() : widget()->size();
              if(widgetSize != newSize) {
                  widgetSize = newSize;
                  updateGeometry();
              }
          }
          return QScrollArea::event(e);
      }
      

      You can have a try.

      M 1 Reply Last reply
      1
      • B Offline
        B Offline
        Bonnie
        wrote on last edited by Bonnie
        #2

        I don't quit understand your need.
        But if you want scrollArea to fit its content width, you can set its horizontal sizePolicy to QSizePolicy::Fixed, this can be done in the designer.
        Please note that the size hint of QLineEdit doesn't grow with its content text.
        So if you want to show all the text in QLineEdit, you may need to set its minimum width.

        1 Reply Last reply
        2
        • M Mattia

          Dear all,
          I have to create a scroll area with only the vertical scrolling bar, so I need the width fits exactly the content.
          I have created this example with QtCreator:

          QtCreator.png

          To fit the QScrollArea to the content, I add this code:

          ui.scrollArea->setFixedWidth(ui.scrollAreaWidgetContents->minimumSizeHint().width());
          

          But this does not produce the wanted result:

          GUI.png

          I have noticed that the problem in this example can be solved setting the QWidget of the scroll area as horizontal layout and removing the nested horizontal layout. The problem is that in my project I will have many widgets inside the scroll area, so I can't avoid to set it as vertical layout and to put inside many horizontal layouts and/or tabs.

          How should I solve this problem?

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #3

          @Mattia You did not set layout on your central widget

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          M 1 Reply Last reply
          0
          • M Offline
            M Offline
            Mattia
            wrote on last edited by
            #4

            I need to programmatically resize the width of the QScrollArea according the width of its content. I can't fix the width before because the content can change.

            ui.scrollArea->setFixedWidth(ui.scrollAreaWidgetContents->minimumSizeHint().width());
            

            This should work, but like I said if I nest the content inside a vertical layout, this command does not do its job anymore...

            1 Reply Last reply
            0
            • B Offline
              B Offline
              Bonnie
              wrote on last edited by Bonnie
              #5

              But by setting QSizePolicy::Fixed, the scrollArea's width will be automaticlly adjusted to the content's size hint.
              When the content changes, as long as its size hint changes, then the width of scrollArea will also change.
              You may have a try on it.

              M 1 Reply Last reply
              1
              • jsulmJ jsulm

                @Mattia You did not set layout on your central widget

                M Offline
                M Offline
                Mattia
                wrote on last edited by
                #6

                @jsulm Yes, I did. Look at the first screenshot, it has a Grid Layout.

                1 Reply Last reply
                0
                • B Bonnie

                  But by setting QSizePolicy::Fixed, the scrollArea's width will be automaticlly adjusted to the content's size hint.
                  When the content changes, as long as its size hint changes, then the width of scrollArea will also change.
                  You may have a try on it.

                  M Offline
                  M Offline
                  Mattia
                  wrote on last edited by
                  #7

                  @Bonnie I have tried, but it doesn't change anything. Already the function setFixedWidth(...) does it.

                  B 1 Reply Last reply
                  0
                  • M Mattia

                    @Bonnie I have tried, but it doesn't change anything. Already the function setFixedWidth(...) does it.

                    B Offline
                    B Offline
                    Bonnie
                    wrote on last edited by Bonnie
                    #8

                    @Mattia Would you mind to share your ui file?
                    I'd like to try it myself.

                    M 2 Replies Last reply
                    0
                    • JonBJ Online
                      JonBJ Online
                      JonB
                      wrote on last edited by JonB
                      #9

                      @Mattia , @Bonnie
                      I'm following this one, because I'm also learning about QScrollArea behaviour. I'd just like to throw in a quote from https://doc.qt.io/qt-5/qscrollarea.html#widgetResizable-prop

                      Regardless of this property, you can programmatically resize the widget using widget()->resize(), and the scroll area will automatically adjust itself to the new size.

                      Which implies we shouldn't need to be doing stuff ourselves on the QScrollArea to make it fit when the content resizes??

                      EDIT And I see now from your file below that you are setting widgetResizable to true, which means you are resizing the widget to fit the scrollarea, when maybe you want the scrollarea to resize to fit the widget instead??

                      1 Reply Last reply
                      0
                      • B Bonnie

                        @Mattia Would you mind to share your ui file?
                        I'd like to try it myself.

                        M Offline
                        M Offline
                        Mattia
                        wrote on last edited by
                        #10

                        @Bonnie Sure!

                        main.cpp

                        #include "QtGuiApplication1.h"
                        #include <QtWidgets/QApplication>
                        #include <Windows.h>
                        
                        int main(int argc, char *argv[])
                        {
                        	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
                        	QApplication a(argc, argv);
                        	QtGuiApplication1 w;
                        
                        	w.show();
                        	return a.exec();
                        }
                        

                        QtGuiApplication1.h

                        #pragma once
                        
                        #include <QtWidgets/QMainWindow>
                        #include "ui_QtGuiApplication1.h"
                        
                        class QtGuiApplication1 : public QMainWindow
                        {
                        	Q_OBJECT
                        
                        public:
                        	QtGuiApplication1(QWidget *parent = Q_NULLPTR);
                        
                        private:
                        	Ui::QtGuiApplication1Class ui;
                        };
                        

                        QtGuiApplication1.cpp

                        #include "QtGuiApplication1.h"
                        
                        QtGuiApplication1::QtGuiApplication1(QWidget *parent)
                        	: QMainWindow(parent)
                        {
                        	QString text;
                        	ui.setupUi(this);
                        
                        	ui.scrollArea->setFixedWidth(ui.scrollAreaWidgetContents->minimumSizeHint().width());
                        }
                        

                        QtGuiApplication1.ui

                        <?xml version="1.0" encoding="UTF-8"?>
                        <ui version="4.0">
                         <class>QtGuiApplication1Class</class>
                         <widget class="QMainWindow" name="QtGuiApplication1Class">
                          <property name="geometry">
                           <rect>
                            <x>0</x>
                            <y>0</y>
                            <width>411</width>
                            <height>289</height>
                           </rect>
                          </property>
                          <property name="windowTitle">
                           <string>QtGuiApplication1</string>
                          </property>
                          <widget class="QWidget" name="centralWidget">
                           <property name="minimumSize">
                            <size>
                             <width>225</width>
                             <height>0</height>
                            </size>
                           </property>
                           <layout class="QHBoxLayout" name="horizontalLayout">
                            <item>
                             <widget class="QScrollArea" name="scrollArea">
                              <property name="sizePolicy">
                               <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
                                <horstretch>0</horstretch>
                                <verstretch>0</verstretch>
                               </sizepolicy>
                              </property>
                              <property name="horizontalScrollBarPolicy">
                               <enum>Qt::ScrollBarAsNeeded</enum>
                              </property>
                              <property name="widgetResizable">
                               <bool>true</bool>
                              </property>
                              <widget class="QWidget" name="scrollAreaWidgetContents">
                               <property name="geometry">
                                <rect>
                                 <x>0</x>
                                 <y>0</y>
                                 <width>338</width>
                                 <height>214</height>
                                </rect>
                               </property>
                               <property name="sizePolicy">
                                <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
                                 <horstretch>0</horstretch>
                                 <verstretch>0</verstretch>
                                </sizepolicy>
                               </property>
                               <layout class="QVBoxLayout" name="verticalLayout">
                                <item>
                                 <layout class="QHBoxLayout" name="horizontalLayout_2">
                                  <item>
                                   <widget class="QLabel" name="label_2">
                                    <property name="text">
                                     <string>LongSizeTextLabel</string>
                                    </property>
                                   </widget>
                                  </item>
                                  <item>
                                   <widget class="QLineEdit" name="lineEdit">
                                    <property name="sizePolicy">
                                     <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
                                      <horstretch>0</horstretch>
                                      <verstretch>0</verstretch>
                                     </sizepolicy>
                                    </property>
                                    <property name="text">
                                     <string/>
                                    </property>
                                   </widget>
                                  </item>
                                  <item>
                                   <widget class="QPushButton" name="pushButton">
                                    <property name="text">
                                     <string>PushButton</string>
                                    </property>
                                   </widget>
                                  </item>
                                 </layout>
                                </item>
                               </layout>
                              </widget>
                             </widget>
                            </item>
                            <item>
                             <widget class="QLabel" name="label">
                              <property name="text">
                               <string>TextLabel</string>
                              </property>
                             </widget>
                            </item>
                           </layout>
                          </widget>
                          <widget class="QMenuBar" name="menuBar">
                           <property name="geometry">
                            <rect>
                             <x>0</x>
                             <y>0</y>
                             <width>411</width>
                             <height>22</height>
                            </rect>
                           </property>
                          </widget>
                          <widget class="QToolBar" name="mainToolBar">
                           <attribute name="toolBarArea">
                            <enum>TopToolBarArea</enum>
                           </attribute>
                           <attribute name="toolBarBreak">
                            <bool>false</bool>
                           </attribute>
                          </widget>
                          <widget class="QStatusBar" name="statusBar"/>
                         </widget>
                         <layoutdefault spacing="6" margin="11"/>
                         <resources>
                          <include location="QtGuiApplication1.qrc"/>
                         </resources>
                         <connections/>
                        </ui>
                        
                        1 Reply Last reply
                        0
                        • B Bonnie

                          @Mattia Would you mind to share your ui file?
                          I'd like to try it myself.

                          M Offline
                          M Offline
                          Mattia
                          wrote on last edited by
                          #11

                          @Bonnie Did you do any test with the source code?

                          B 1 Reply Last reply
                          0
                          • M Mattia

                            @Bonnie Did you do any test with the source code?

                            B Offline
                            B Offline
                            Bonnie
                            wrote on last edited by
                            #12

                            @Mattia Yes, seems when inside a vertical layout, the width of sizehint is not correct right after the content changing.
                            I did some tests, even tried subclassing QScrolArea, but still not get a expected result.

                            M 1 Reply Last reply
                            0
                            • B Bonnie

                              @Mattia Yes, seems when inside a vertical layout, the width of sizehint is not correct right after the content changing.
                              I did some tests, even tried subclassing QScrolArea, but still not get a expected result.

                              M Offline
                              M Offline
                              Mattia
                              wrote on last edited by
                              #13

                              @Bonnie Thanks.
                              Let me know if you find a solution can work around this issue!

                              B 1 Reply Last reply
                              0
                              • M Mattia

                                @Bonnie Thanks.
                                Let me know if you find a solution can work around this issue!

                                B Offline
                                B Offline
                                Bonnie
                                wrote on last edited by Bonnie
                                #14

                                @Mattia Hi, I think I kind of find a solution.

                                1. (in cpp) Remove that setFixedWidth code.
                                2. (in ui) Set horizontal size policy of scrollArea to "Fixed" as I mentioned.
                                3. (in ui) Reset minimumSize of centralWidget to default (0 x 0)
                                4. (in ui) Promote scrollArea to new class: ModScrollArea

                                modscrollarea.h

                                #ifndef MODSCROLLAREA_H
                                #define MODSCROLLAREA_H
                                
                                #include <QScrollArea>
                                
                                class ModScrollArea : public QScrollArea
                                {
                                    Q_OBJECT
                                public:
                                    explicit ModScrollArea(QWidget *parent = nullptr);
                                    QSize sizeHint() const;
                                protected:
                                    bool event(QEvent *e);
                                private:
                                    mutable QSize widgetSize;
                                };
                                
                                #endif // MODSCROLLAREA_H
                                

                                modscrollarea.cpp

                                #include "modscrollarea.h"
                                
                                #include <QEvent>
                                #include <QScrollBar>
                                
                                ModScrollArea::ModScrollArea(QWidget *parent) : QScrollArea(parent)
                                {
                                }
                                
                                QSize ModScrollArea::sizeHint() const
                                {
                                    int f = 2 * frameWidth();
                                    QSize sz(f, f);
                                    int h = fontMetrics().height();
                                    if (widget()) {
                                        if(!widgetSize.isValid())
                                            widgetSize = widgetResizable() ? widget()->sizeHint() : widget()->size();
                                        sz += widgetSize;
                                    } else {
                                        sz += QSize(12 * h, 8 * h);
                                    }
                                    if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOn)
                                        sz.setWidth(sz.width() + verticalScrollBar()->sizeHint().width());
                                    if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn)
                                        sz.setHeight(sz.height() + horizontalScrollBar()->sizeHint().height());
                                    return sz.boundedTo(QSize(sz.width(), 24 * h));
                                }
                                
                                bool ModScrollArea::event(QEvent *e)
                                {
                                    if(e->type() == QEvent::LayoutRequest && widget()) {
                                        QSize newSize = widgetResizable() ? widget()->sizeHint() : widget()->size();
                                        if(widgetSize != newSize) {
                                            widgetSize = newSize;
                                            updateGeometry();
                                        }
                                    }
                                    return QScrollArea::event(e);
                                }
                                

                                You can have a try.

                                M 1 Reply Last reply
                                1
                                • B Bonnie

                                  @Mattia Hi, I think I kind of find a solution.

                                  1. (in cpp) Remove that setFixedWidth code.
                                  2. (in ui) Set horizontal size policy of scrollArea to "Fixed" as I mentioned.
                                  3. (in ui) Reset minimumSize of centralWidget to default (0 x 0)
                                  4. (in ui) Promote scrollArea to new class: ModScrollArea

                                  modscrollarea.h

                                  #ifndef MODSCROLLAREA_H
                                  #define MODSCROLLAREA_H
                                  
                                  #include <QScrollArea>
                                  
                                  class ModScrollArea : public QScrollArea
                                  {
                                      Q_OBJECT
                                  public:
                                      explicit ModScrollArea(QWidget *parent = nullptr);
                                      QSize sizeHint() const;
                                  protected:
                                      bool event(QEvent *e);
                                  private:
                                      mutable QSize widgetSize;
                                  };
                                  
                                  #endif // MODSCROLLAREA_H
                                  

                                  modscrollarea.cpp

                                  #include "modscrollarea.h"
                                  
                                  #include <QEvent>
                                  #include <QScrollBar>
                                  
                                  ModScrollArea::ModScrollArea(QWidget *parent) : QScrollArea(parent)
                                  {
                                  }
                                  
                                  QSize ModScrollArea::sizeHint() const
                                  {
                                      int f = 2 * frameWidth();
                                      QSize sz(f, f);
                                      int h = fontMetrics().height();
                                      if (widget()) {
                                          if(!widgetSize.isValid())
                                              widgetSize = widgetResizable() ? widget()->sizeHint() : widget()->size();
                                          sz += widgetSize;
                                      } else {
                                          sz += QSize(12 * h, 8 * h);
                                      }
                                      if (verticalScrollBarPolicy() == Qt::ScrollBarAlwaysOn)
                                          sz.setWidth(sz.width() + verticalScrollBar()->sizeHint().width());
                                      if (horizontalScrollBarPolicy() == Qt::ScrollBarAlwaysOn)
                                          sz.setHeight(sz.height() + horizontalScrollBar()->sizeHint().height());
                                      return sz.boundedTo(QSize(sz.width(), 24 * h));
                                  }
                                  
                                  bool ModScrollArea::event(QEvent *e)
                                  {
                                      if(e->type() == QEvent::LayoutRequest && widget()) {
                                          QSize newSize = widgetResizable() ? widget()->sizeHint() : widget()->size();
                                          if(widgetSize != newSize) {
                                              widgetSize = newSize;
                                              updateGeometry();
                                          }
                                      }
                                      return QScrollArea::event(e);
                                  }
                                  

                                  You can have a try.

                                  M Offline
                                  M Offline
                                  Mattia
                                  wrote on last edited by
                                  #15

                                  @Bonnie thanks, your class works very well and does exactly what I need!!!

                                  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