Геометрия QLayout обновляется с опозданием после изменения размера дочерних элементов в Qt

#qt #qwidget #qlayout

#qt #qwidget #qlayout

Вопрос:

У меня есть QScrollArea, который содержит виджет-оболочку. Виджет-оболочка используется для хранения двух «синих» виджетов, которые позиционируются QVBoxLayout. Синие виджеты имеют фиксированный размер.

Проблема в коде внутри

mousePressEvent

Как только пользователь нажимает кнопку мыши, я хотел бы изменить размер синих виджетов и немедленно переместить область прокрутки так, чтобы верхняя часть второго синего виджета находилась в верхней части окна просмотра.

Однако, похоже, что геометрия оболочки обновляется позже, и поэтому позиция вычисляется неправильно при вызове функции mapTo оболочки.

Как только я снова щелкаю мышью, позиция становится правильной, потому что на этот раз размеры не меняются, а геометрия была обновлена. Как я могу это преодолеть? Есть ли способ заставить оболочку обновить свою геометрию? Использование updateGeometry не работает…

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:

Найдено решение. Просто добавьте wrapper->adjustSize(); после изменения размера.