[Solved] Layout with Scrollbar



  • I am developing an application which requires a dialog which will contain up to several hundred push buttons. I have been experimenting with the flow layout example which I think would be a good starting point but I'm struggling to add a QScrollArea.

    My goal is to build a dialog which will contain only a vertical scrollbar and change the number of button columns when resized to fit the width. The vertical scrollbar allows the user scroll the additional buttons. I would also prefer the layout to organize top to bottom rather than left to right.

    I'm porting code from X/Motif so I am new to Qt. Any simple examples out there to get me started? Thanks.


  • Moderators

    Have a look at "QTableWidget":http://qt-project.org/doc/qt-5.0/qtwidgets/qtablewidget.html. You can add QPushbutton into it using setCellWidget. You can also add columns and rows as per your requirement. If you just want to show only the vertical scrollbar you can disable horizontalscrollbar using setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff)


  • Moderators

    i wouldn't go the overhead with QTableWidget, it's not worth it for such a simple task IMHO.

    the following should do it:
    @
    FlowLayout* flowLayout = new FlowLayout;
    QWidget* scrollAreaContent = new QWidget;
    scrollAreaContent->setLayout( flowLayout );
    QScrollArea* scrollArea = new QScrollArea;
    scrollArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
    scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
    scrollArea->setWidgetResizable( true );
    scrollArea->setWidget( scrollAreaContent );

    // add your buttons the flowLayout ....
    flowLayout->addWidget( button );
    @



  • raven-worx your suggestion is what I have been trying to put together myself without success. I had thought of using the QTableWidget or QGridLayout but both seemed overly complicated for this task.

    I think your code example is how I should proced but in the context of a QGroupBox within a dialog how would I insert the scroll area? I've tried several different ways without success, but then I am very new to Qt. Thanks to both for the replies.


  • Moderators

    show the code you've got so far please.



  • This is the code inside my dialog constructor. Admittedly it doesn't work because I haven't figured out how to get the scrollArea to reside inside the groupBox.

    @my_dialog::my_dialog (QWidget *parent) : QDialog (parent) {

    resize(400, 300);
    buttonBox = new QDialogButtonBox (this);
    buttonBox->setGeometry (QRect(30, 240, 341, 32));
    buttonBox->setOrientation (Qt::Horizontal);
    buttonBox->setStandardButtons (QDialogButtonBox::Cancel|QDialogButtonBox::Ok);

    QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

    QMetaObject::connectSlotsByName (this);

    QGroupBox *groupBox = new QGroupBox (tr("group box"));

    FlowLayout *flowLayout = new FlowLayout;

    QWidget* scrollAreaContent = new QWidget;

    scrollAreaContent->setLayout (flowLayout);

    QScrollArea* scrollArea = new QScrollArea;
    scrollArea = new QScrollArea;
    scrollArea->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
    scrollArea->setVerticalScrollBarPolicy (Qt::ScrollBarAsNeeded);
    scrollArea->setWidgetResizable (true);
    scrollArea->setWidget (scrollAreaContent);

    flowLayout->addWidget (new QPushButton("push_button 1"));
    ...
    flowLayout->addWidget (new QPushButton("push_button N"));

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget (groupBox);

    mainLayout->addWidget (buttonBox);
    setLayout (mainLayout);
    setWindowTitle (tr("Main Dialog"));
    }@


  • Moderators

    Well you add an empty QGroupBox to your mainLayout ;)
    (Also note the memory leak comment in the code)

    @
    my_dialog::my_dialog (QWidget *parent) : QDialog (parent)
    {
    resize(400, 300);
    buttonBox = new QDialogButtonBox (this);
    buttonBox->setGeometry (QRect(30, 240, 341, 32));
    buttonBox->setOrientation (Qt::Horizontal);
    buttonBox->setStandardButtons (QDialogButtonBox::Cancel|QDialogButtonBox::Ok);

    QObject::connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    QObject::connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

    QMetaObject::connectSlotsByName (this);

    QGroupBox *groupBox = new QGroupBox (tr("group box"));

    FlowLayout *flowLayout = new FlowLayout;

    QWidget* scrollAreaContent = new QWidget;
    scrollAreaContent->setLayout (flowLayout);

    QScrollArea* scrollArea = new QScrollArea;
    scrollArea = new QScrollArea; //MEMORY LEAK! remove this line
    scrollArea->setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
    scrollArea->setVerticalScrollBarPolicy (Qt::ScrollBarAsNeeded);
    scrollArea->setWidgetResizable (true);
    scrollArea->setWidget (scrollAreaContent);

    flowLayout->addWidget (new QPushButton("push_button 1"));
    ...
    flowLayout->addWidget (new QPushButton("push_button N"));

    //you were missing the following lines
    QVBoxLayout* groupBoxLayout = new QVBoxLayout;
    groupBoxLayout->addWidget(scrollArea);
    groupBox->setLayout( groupBoxLayout);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget (groupBox);
    mainLayout->addWidget (buttonBox);
    setLayout (mainLayout);
    setWindowTitle (tr("Main Dialog"));
    }
    @



  • raven-worx you have solved my dilemna. Frankly I searched hard to locate an example such as you have presented but found none. Hopefully this will help others. It has certainly educated me. Thank you so much.


Log in to reply
 

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