Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QScrollArea does not scroll to maximum after widgets have been added

My setup looks like this:

Main Window
  |- QHBoxLayout
       |- Some Widgets
       |- QScrollArea
       |    |- QHBoxLayout
       |         |- QGridLayout
       |              |- Widgets dynamically loaded in at runtime
       |         |- QVBoxLayout
       |- Some Widgets

After I added in Widgets I want the Scroll Area to completely scroll down. I did this by:

this->ui->gridLayout_table->addWidget(/*Widget*/); // this works perfectly nice
this->ui->gridLayout_table->addWidget(/*Widget*/); // this also works perfectly nice
this->ui->scrollArea->verticalScrollBar()->setValue(this->ui->scrollArea->verticalScrollBar()->maximum());

At the last command it scrolls to maximum minus the height of the newly added widgets. Is there any way to flush the changes before scrolling?

Thanks in advance Lukas

like image 908
Lukas Avatar asked Nov 07 '13 12:11

Lukas


2 Answers

Python version for the rangeChanged method:

scroll_area = QtGui.QScrollArea()
scroll_bar = scroll_area.verticalScrollBar()
scroll_bar.rangeChanged.connect(lambda: scroll_bar.setValue(scroll_bar.maximum()))

By connecting the rangeChanged method to the scrolldown, it ensures that each time there is a change in range the scrollbar will scroll down to the max.

Source

like image 159
TrakJohnson Avatar answered Dec 28 '22 06:12

TrakJohnson


I've had the same problem. I found a work-around, which might be useful for you as well.

Using scrollBar->setValue(scrollBar->maximum()); does not work when being used right after having added widgets to the scrolled area. The maximum value of the scroll bar simply is not updated yet.

However it does work if you have a button that the user has to click just to adjust the scroll bar's position to the maximum. It seems that the scroll area notifies its scroll bar asynchronously (through signal) only. So I simply added a hidden button pb_AdjustScrollBar to my widget and simulated a click, using the animateClick(int) method after having added widgets to the scrolled area. Once the signal clicked(bool) is received for the AdjustScrollBar button, I then trigger the scrollBar to use the maximum position with:

scrollBarPtr->triggerAction(QAbstractSlider::SliderToMaximum);

Notes: the animateClick timeout must be set to something like 100ms (default). Putting the timeout much shorter has caused the scrollBar not to update to its real maximum. However I guess 100ms is fast enough for user interactions anyhow.

Still I would be curious to know, how this issue can be solved in a smarter way.

like image 31
famoses Avatar answered Dec 28 '22 06:12

famoses