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.
QtWS25 Last Chance

[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
    #1

    Hello,

    I'm trying to use a QScrollArea where only the vertical scrollbar is in use.

    I've set setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    But that simply makes the internal widgets clip on the right side of the screen.

    What I've done so far is ovride the resizeEvent and set:
    widget()->setMinimumWidth(event->size().width())

    This does the trick a lot of the time... but if the internal widgets needs a size greater then what the resize event is giving then the internal widgets start drawing on top of each other.

    Does anyone have any ideas of how to resolve this?

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