I have a QScrollArea which holds a wrapper widget. The wrapper widget is used to hold two 'blue' widgets which are positioned by QVBoxLayout. The blue widgets have a fixed size.
The problem is in the code inside
mousePressEvent
Once the user presses the mouse button, I would like to resize the blue widgets and immediately move the scrollArea so that the top of the second blue widget is at the top of the viewport.
However, it seems that the geometry of the wrapper is updated later and therefore the position is not calculated correctly by calling mapTo function of wrapper.
Once I click the mouse again the position becomes correct, because this time the sizes don't change and the geometry was updated. How can I overcome this? Is there a way to force the wrapper to update its geometry? Using updateGeometry doesn't work...
mainwindow.c:
#include "mainwindow.h"
#include <QScrollArea>
#include <QVBoxLayout>
#include <QDebug>
#include <QScrollBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// pallete to color widgets blue
QPalette pal = palette();
pal.setColor(QPalette::Background, Qt::blue);
QSize widgetSize(200,500); // will be used to set size of widgets
scrollArea = new QScrollArea;
setCentralWidget(scrollArea);
wrapper = new QWidget(scrollArea); //wrapper to hold the layout and blue widgets
QVBoxLayout *layout = new QVBoxLayout(wrapper);
wrapper->setLayout(layout);
//first blue widget
a1 = new QWidget(wrapper);
a1->setAutoFillBackground(true);
a1->setPalette(pal);
a1->setFixedSize(widgetSize);
// second blue widget
a2 = new QWidget(wrapper);
a2->setAutoFillBackground(true);
a2->setPalette(pal);
a2->setFixedSize(widgetSize);
scrollArea->setWidgetResizable( true );
scrollArea->setWidget(wrapper);
layout->addWidget(a1);
layout->addWidget(a2);
}
void MainWindow::mousePressEvent(QMouseEvent *event)
{
// Resize blue widgets and move scrollArea to top-left corner of a2
QSize newSize(200,510); // 10 px heigher than before
//!! This is where is seems to break...
a1->setFixedSize(newSize);
a2->setFixedSize(newSize);
//!! The mapTo uses the old geometry
scrollArea->verticalScrollBar()->setValue(a2->mapTo(wrapper, {0,0}).y());
}
MainWindow::~MainWindow() {};
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QScrollArea>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QScrollArea *scrollArea;
QWidget *wrapper;
QWidget *a1,*a2;
void mousePressEvent(QMouseEvent *event) override;
};
#endif // MAINWINDOW_H