spraff
spraff

Reputation: 33385

Why isn't this QWidget updating its geometry?

I have a QWidget which gains child widgets after it has been created and shown. It ends up crowded, like this:

enter image description here

I have tried QWidget::updateGeometry, QLayout::invalidate, and QLayout::activate, but to no effect.

Here's the outline of the code.

void MainWindow :: show_dialog ()
{
    QDialog d;
    auto l = new QHBoxLayout (& d);
    auto tabs = new QTabWidget ();
    l -> addWidget (tabs);

    auto w = new MyWidget ();

    tabs -> addTab (w, tr ("..."));

    d .exec ();
}

MyWidget :: MyWidget ()
{
    auto l = new QGridLayout (this);

    m_scroll_area = new QScrollArea ();
    m_scroll_contents = new QWidget ();
    m_layout = new QGridLayout (m_scroll_contents);

    l -> addWidget (m_scroll_area, 0, 0, 1, 2);

    for (auto i : things ())
        add (i);

    m_scroll_area -> setWidget (m_scroll_contents);
}

void MyWidget :: add (foo)
{
    m_layout -> addWidget (x(foo), m_row);
    m_layout -> addWidget (y(foo), m_row);
    ++m_row;

    // This bit was added in an attempt to fix the problem,
    // it does nothing.

    for (QWidget * w = m_scroll_contents; w; w = w -> parentWidget ())
    {
        qWarning ("%p : %p", (void *)w, (void *)w->layout ());

        w -> updateGeometry ();

        if (w -> layout ())
        {
            w -> layout () -> invalidate ();
            w -> layout () -> activate ();
        }

        w -> updateGeometry ();
    }
}

The idea is that MyWidget::add can get called later on to add another row and the geometry will recalculate, but I can't seem to fix the crush.

Somewhat surprisingly, the qWarning line indicates that not every widget up to the root has a layout. I don't know if this is relevant. The output is something like this:

0xa60a40 : 0xa607c0                // m_scroll_contents which has QGridLayout
0x82bb70 : 0x0                     // m_scroll_area I assume
0x9aec80 : 0x0                     // MyWidget, I assume, but this should have a QGridLayout (!)
0xa5e9c0 : 0xa33370                // In which case this is QTabWidget
0x9b42d0 : 0x8b7800                // QDialog ?
0x9aca30 : 0x0                     // ?
0x7fffd45d0950 : 0xa262a0          // ?

Upvotes: 0

Views: 438

Answers (1)

Rostislav
Rostislav

Reputation: 3977

By default, QScrollArea does not resize the widget it contains (in your case m_scroll_contents). You should call m_scroll_area->setWidgetResizable(true); to enable this behaviour.

Upvotes: 1

Related Questions