perelo
perelo

Reputation: 495

Refreshing a layout requires a resize?

I'm trying to refresh a QWidget on a QMainWindow, actually I just change it's layout which is a QVBoxLayout filled with QGroupBoxs

So, when a certain signal is emited, the QMainWindow hide all the QWidgets present in it's layout (before deleting them), then make new ones and show() them. The thing is that, 90% of the time, the new list of QWidgets is larger. So when the refresh is done, the new QWidgets actually show but the QMainWindow is at the old size ! A simple resize (with mouse) makes the QMainWindow to be resized to the proper size.

Is there any function to apply on the QWidget ? on it's layout ? on the QMainWindow ?

I tried adjustSize() on each of them, but didn't work

Upvotes: 1

Views: 960

Answers (1)

It's supposed to naturally work, so you're doing something wrong. The default sizeConstraint of the layout on a widget is to only grow the widget if it's too small. You can change it to both grow and shrink the widget.

  1. You must be adding the new widgets to the layout.

  2. Your main window must not have a minimumSize(). If you derive from a widget that does return a nonzero minimumSize(), you must override it and return a zero size.

  3. You don't have to hide the child widgets before deleteing them. It's pointless. Just delete them, Qt handles it properly.

See the complete example below. Tested on OS X and Windows XP + MSVC.

//main.cpp
#include <cstdlib>
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QHBoxLayout>
#include <QPushButton>

static int pick() { const int N = 10; return (qrand()/N) * N / (RAND_MAX/N); }

class Window : public QWidget {
    Q_OBJECT
    QLayout * layout;
public:
    Window() {
        layout = new QHBoxLayout;
        QPushButton * button;
        button = new QPushButton("Randomize", this);
        connect(button, SIGNAL(clicked()), SLOT(randomize()));
        layout->addWidget(button);
        button = new QPushButton("Grow", this);
        button->setCheckable(true);
        connect(button, SIGNAL(toggled(bool)), SLOT(grow(bool)));
        layout->addWidget(button);
        setLayout(layout);
    }
private slots:
    void randomize() {
        // remove old labels
        foreach (QObject * o, findChildren<QLabel*>()) { delete o; }
        // add some new labels
        int N = pick();
        while (N--) {
            layout->addWidget(new QLabel(QString(pick(), 'a' + pick()), this));
        }
    }
    void grow(bool shrink)
    {
        QPushButton * button = qobject_cast<QPushButton*>(sender());
        if (shrink) {
            button->setText("Grow && Shrink");
            layout->setSizeConstraint(QLayout::SetFixedSize);
        } else {
            button->setText("Grow");
            layout->setSizeConstraint(QLayout::SetDefaultConstraint);
        }
    }
};

int main(int c, char ** v)
{
    QApplication app(c,v);
    Window w;
    w.show();
    return app.exec();
}

#include "main.moc"

Upvotes: 1

Related Questions