[SOLVED] QScrollArea: Vertical scroll only.



  • 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?



  • 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)
    @



  • 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.



  • 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;
    }@



  • 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.



  • 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?



  • Hello,

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



  • [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);
    }
    @



  • [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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.