0
votes

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
1

1 Answers

0
votes

Found a solution. Simply add wrapper->adjustSize(); after the size changes.