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

[SOLVED] QScrollArea: Vertical scroll only.

Scheduled Pinned Locked Moved General and Desktop
12 Posts 9 Posters 37.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.
  • L Offline
    L Offline
    leon.anavi
    wrote on last edited by
    #2

    Try to disable the horizontal scroll and enable the vertical scroll if needed usi the following methods of "QAbstractScrollArea":http://doc.qt.nokia.com/4.8-snapshot/qabstractscrollarea.html#verticalScrollBarPolicy-prop

    @
    QAbstractScrollArea::setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff )
    QAbstractScrollArea::setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded)
    @

    http://anavi.org/

    1 Reply Last reply
    0
    • 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