I am using Qt 5.9.1 on an Oracle virtual box 6.0 emulating a linux box. The MySQL database is MariaDB.
I am trying to display user information on a QScrollArea and I have up and down buttons to jump back and forth between users instead of displaying the vertical scrollbar. When the first user is displayed, the up button should be disabled since there is no other users before of the current user. When the last user is displayed, the down button should be disabled since there is no other users after the current user. For debugging purposes, I added a QMessageBox::information and everything works fine. If I remove the QMessageBox, the buttons do not set their enabled property to false.

In the constructor, the signals are attached to the slots:
Qt Code:
  1. connect(ui_previous_user_pushButton, SIGNAL(clicked()), this, SLOT(SlotUserUp()));
  2. connect(ui_next_user_pushButton, SIGNAL(clicked()), this, SLOT(SlotUserDown()));
  3. connect(ui_scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(SlotUserPositionChanged(int)));
To copy to clipboard, switch view to plain text mode 

For each user, the following is added to the QScrollArea:
Qt Code:
  1. QFrame* layout_frame = new QFrame(this);
  2. QHBoxLayout* h_box_layout = new QHBoxLayout();
  3. h_box_layout->addStretch();
  4. QFrame* user_frame = new QFrame(this);
  5. ...
  6. QGridLayout* frame_layout = new QGridLayout();
  7. ...
  8. user_frame->setObjectName("user_frame");
  9. QLabel* user_label = new QLabel(QString(tr("Operator : %1")).arg(user->GetName()), this);
  10. ...
  11. // Add widgets to frame layout
  12. frame_layout->addWidget(user_label, 0,0,1,6,Qt::AlignLeft);
  13. ...
  14. user_frame->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
  15. user_frame->setLayout(frame_layout);
  16. hbox_layout->addWidget(user_frame);
  17. h_box_layout->addStretch();
  18. layout_frame->setLayout(h_box_layout);
  19. main_layout->addWidget(layout_frame);
  20. ...
To copy to clipboard, switch view to plain text mode 

I then create a list of the user frames. m_user_list is a private member variable of type QList<QFrame*>. The list contains 4 widgets on the database I am using, the min Y value is 9 and the max Y value is 1213. As you will find, I tried to process the events, since it seems like a repaint problem:
Qt Code:
  1. m_user_list = ui_scrollArea->findChildren<QFrame *>(QString("user_frame"),Qt::FindChildrenRecursively);
  2. if (!m_user_list.isEmpty())
  3. {
  4. //QMessageBox::information(0, "Empty?", "No");
  5. qApp->processEvents();
  6. int min = m_user_list.at(0)->parentWidget()->y(); // The minimum possible Y value of a user frame.
  7. int max = 0; // The maximum possible Y value of a user frame.
  8. for (int = 0; i< m_user_list.size(0; i++)
  9. {
  10. if (min > m_user_list.at(i)->parentWidget()->y())
  11. {
  12. min = m_user_list.at(i)->parentWidget()->y();
  13. }
  14. if (max < m_user_list.at(i)->parentWidget()->y())
  15. {
  16. max = m_user_list.at(i)->parentWidget()->y();
  17. }
  18. }
  19. QMessageBox::information(0,"Min/Max",QString("Min: %1, Max: %2").arg(min).arg(max));
  20. qApp->processEvents();
  21. ui_scrollArea->verticalScrollBar()->setMinimum(min);
  22. ui_scrollArea->verticalScrollBar()->setMaximum(max);
  23. // ui_scrollArea->verticalScrollBar()->setSliderPosition(min);
  24. ui_scrollArea->verticalScrollBar()->setValue(min);
  25. qApp->processEvents();
  26. }
  27. ...
To copy to clipboard, switch view to plain text mode 

The up button click is connected to the following code:
Qt Code:
  1. void OD:SlotUserUp(void)
  2. {
  3. int difference = INT_MAX; // The difference between the scrollbar value and a previous user.
  4. int closest_index = 0; // The index in the list of the closest label of a previous user.
  5. if (!m_user_list.isEmpty())
  6. {
  7. for(int i=0; i<m_user_list.size(); i++)
  8. {
  9. if (m_user_list.at(i)->parentWidget()->y() < ui_scrollArea->verticalScrollBar()->value())
  10. {
  11. if (difference > (ui_scrollArea->verticalScrollBar()->value() - m_user_list.at(i)->parentWidget()->y()))
  12. {
  13. difference = (ui_scrollArea->verticalScrollBar()->value() - m_user_list.at(i)->parentWidget()->y());
  14. closest_index = i;
  15. }
  16. }
  17. }
  18. ui_scrollArea->verticalScrollBar()->setValue(m_user_list.at(closest_index)->parentWidget()->y());
  19. }
  20. }
To copy to clipboard, switch view to plain text mode 
I have similar code for the down button.

When the scrollbar value changes, this is the method that is run:
Qt Code:
  1. void OD::SlotUserPositionChanged(int position)
  2. {
  3. Q_UNUSED(position);
  4. if (ui_scrollArea->verticalScrollBar()->value() == ui_scrollArea->verticalScrollBar()->minimum())
  5. {
  6. ui_previous_user_pushButton->setEnabled(false);
  7. }
  8. else
  9. {
  10. ui_previous_user_pushButton->setEnabled(true);
  11. }
  12. if (ui_scrollArea->verticalScrollBar()->value() == ui_scrollArea->verticalScrollBar()->maximum())
  13. {
  14. ui_next_user_pushButton->setEnabled(false);
  15. }
  16. else
  17. {
  18. ui_next_user_pushButton->setEnabled(true);
  19. }
  20. }
To copy to clipboard, switch view to plain text mode 

Any help will be greatly appreciated!