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
13 Posts 10 Posters 37.9k 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.
  • 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
                    • S Offline
                      S Offline
                      Steve King
                      wrote last edited by
                      #13

                      Thank you for the tip;
                      I'm using Python, so I rewrote like this, and it works:

                      class VerticalScrollArea(QtWidgets.QScrollArea):

                      def __init__(self):
                          super().__init__()
                          self.setWidgetResizable(True)
                          self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
                          self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)    
                      
                      def eventFilter(self, object, event):
                          # This works because QScrollArea::setWidget installs an eventFilter on the widget
                          if object is not None and object == self and event.type() == QEvent.Resize:
                              self.setMinimumWidth(self.minimumSizeHint().width() + self.verticalScrollBar.width())
                      
                          return super().eventFilter(object, event)
                      
                      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