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. [SOLVED] QScrollArea: Vertical scroll only.

[SOLVED] QScrollArea: Vertical scroll only.

Scheduled Pinned Locked Moved General and Desktop
12 Posts 9 Posters 37.4k 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.
  • U Offline
    U Offline
    ultim8
    wrote on last edited by
    #3

    Sigh...

    In my original message I have already mentioned that I did exactly that already... but that is not enough.

    What I want:

    The QScrollArea should scroll vertically (as it does normally).

    Horizontally it should behave exactly like a QWidget

    -meaning internal widgets resize to fit it's available space
    -also it is not allowed to resize smaller then the internal widgets permit.

    1 Reply Last reply
    0
    • U Offline
      U Offline
      ultim8
      wrote on last edited by
      #4

      Found a solution! simply look for resize events for the scrollAreaWithContents widgets and set the scrollArea's minimum width to the scrollAreaWithContents minimumSizeHint().with():

      @VerticalScrollArea::VerticalScrollArea(QWidget *parent)
      : QScrollArea(parent)
      {
      setWidgetResizable(true);
      setFrameStyle(QFrame::NoFrame);
      setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
      setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
      m_scrollAreaWidgetContents = new QWidget(this);
      m_scrollAreaWidgetContents->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
      QVBoxLayout *baseLayout = new QVBoxLayout(m_scrollAreaWidgetContents);
      setWidget(m_scrollAreaWidgetContents);
      m_scrollAreaWidgetContents->installEventFilter(this);
      }

      bool VerticalScrollArea::eventFilter(QObject *o, QEvent *e)
      {
      if(o == m_scrollAreaWidgetContents && e->type() == QEvent::Resize)
      setMinimumWidth(m_scrollAreaWidgetContents->minimumSizeHint().width() + verticalScrollBar()->width());

      return false;
      }@

      1 Reply Last reply
      1
      • O Offline
        O Offline
        ostlerc
        wrote on last edited by
        #5

        Thanks for solving this problem! However, unless your minimum size changes on resize events you will only need to set this once after a show event.

        1 Reply Last reply
        0
        • G Offline
          G Offline
          galinette
          wrote on last edited by
          #6

          Thanks for the solution!

          By the way, this is close to be a bug. A QScrollArea with horizontal bars switched off should set its minimum width by considering the minimum width of the contents widget, no?

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mstone1959
            wrote on last edited by
            #7

            Hello,

            I'm fairly new to Qt and I would like to know how I implement the VerticalScrollArea class to correct the problem?

            1 Reply Last reply
            0
            • U Offline
              U Offline
              ultim8
              wrote on last edited by
              #8

              [quote author="mstone1959" date="1389726822"]Hello,

              I'm fairly new to Qt and I would like to know how I implement the VerticalScrollArea class to correct the problem?[/quote]

              You will want to create a new class "VerticalScrollArea" derived off of QScrollArea.

              header:
              @#ifndef VERTICALSCROLLAREA_H
              #define VERTICALSCROLLAREA_H

              #include <QScrollArea>

              class VerticalScrollArea : public QScrollArea
              {
              Q_OBJECT
              public:
              explicit VerticalScrollArea(QWidget *parent = 0);

              virtual bool eventFilter(QObject *o, QEvent *e);

              };

              #endif // VERTICALSCROLLAREA_H@

              Implementation:
              @#include <QEvent>
              #include <QScrollBar>

              #include "verticalscrollarea.h"

              VerticalScrollArea::VerticalScrollArea(QWidget *parent) :
              QScrollArea(parent)
              {
              setWidgetResizable(true);
              setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
              setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
              }

              bool VerticalScrollArea::eventFilter(QObject *o, QEvent *e)
              {
              // This works because QScrollArea::setWidget installs an eventFilter on the widget
              if(o && o == widget() && e->type() == QEvent::Resize)
              setMinimumWidth(widget()->minimumSizeHint().width() + verticalScrollBar()->width());

              return QScrollArea::eventFilter(o, e);
              }
              @

              1 Reply Last reply
              5
              • T Offline
                T Offline
                trusktr
                wrote on last edited by
                #9

                [quote author="galinette" date="1360135272"]Thanks for the solution!

                By the way, this is close to be a bug. A QScrollArea with horizontal bars switched off should set its minimum width by considering the minimum width of the contents widget, no?[/quote]

                I don't think so. I think setting the horizontal scroll bar to off should simply not show a horizontal scroll bar (but that doesn't mean the area can't be scrolled, e.g. with touch and drag). Changing the width of the scroll area should be a separate step if the developer so desires.

                1 Reply Last reply
                1
                • J Offline
                  J Offline
                  Jacques L.
                  wrote on last edited by
                  #10

                  Although old, this topic saved me time. So here are my two cents here. I change the constructor to this to support one-finger scrolling on Android (didn't try for iOS yet):

                  CVScrollArea::CVScrollArea(QWidget *parent)
                     : QScrollArea(parent)
                  {
                     setWidgetResizable(true);
                     setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                  
                  // One-finger swipe/scroll while default in Qt is 3-fingers!
                     QScroller::grabGesture(this->viewport(), QScroller::LeftMouseButtonGesture);
                  
                  // No scroll bar for Android (and probably iOS)
                  #ifndef Q_OS_ANDROID
                        this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
                  #else
                        this->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
                  #endif
                  }
                  
                  1 Reply Last reply
                  1
                  • V Offline
                    V Offline
                    viteo
                    wrote on last edited by viteo
                    #11

                    Hello from 2022.
                    Used all my google-fu to find this answer. Thank you!
                    I confirm that there is still no standard QVerticalScroll, you have to implement it yourself with overriding eventFilter.

                    p.s.
                    ...but the eventFilter() get a lot of calls from everythin (mouse, activation, resize etc)
                    I suggest to override resizeEvent(). Here is my approach:

                    HEADER:

                    protected:
                        void resizeEvent(QResizeEvent *);
                    

                    SOURCE:

                    void ClassName::resizeEvent(QResizeEvent* event)
                    {
                        setMinimumWidth(widget()->minimumSizeHint().width() + verticalScrollBar()->width());
                        QScrollArea::resizeEvent(event);
                    }
                    
                    1 Reply Last reply
                    3
                    • V Offline
                      V Offline
                      Vaquita Tim
                      wrote on last edited by
                      #12

                      Every couple of years this comes up...

                      Certainly setMinimumWidth() is key - it needs to fit the size of the scrolled widget().

                      In my derived class I actually connected a slot to the horizontal scroll bar, which changes if the widget() changes width

                      connect( horizontalScrollBar(), &QAbstractSlider::rangeChanged, this, &CVerticalScrollArea::ResetMinWidth );
                      

                      then I calculate the minumum width bearing in mind the frame width. I do the same for the minimumSizeHint too (although maybe this is not required).

                      QSize CVerticalScrollArea::minimumSizeHint() const
                      {
                      	QSize MinSize( QScrollArea::minimumSizeHint() );
                      	const QWidget * pWidget( widget() );
                      	if( pWidget )
                      	{
                      		const int FrameWidth( 2 * frameWidth() );
                      		const int TotalWidth( pWidget->minimumSizeHint().rwidth() + FrameWidth );
                      		if( TotalWidth > MinSize.width() )
                      			MinSize.setWidth( TotalWidth );
                      	}
                      	return MinSize;
                      }
                      
                      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