1
votes

I have a widget with QVBoxLayout as the main layout and QGridLayout as a child layout nested inside the main one. There is toggle button which shows/hides certain widgets in the grid layout. After updating visibility I want to adjust (minimize) the size of the widget. But resizing does not work correctly when child widgets get hidden, the widget size stays the same, it is not shrinked as I would expect. Moreover the widget is not correctly repainted, some bad button fragments remain visible. I observed that this does not happen if the grid layout is the main one (i.e. there is no vertical layout), but if it is nested inside another layout it behaves strange. Any ideas how to fix this?

widget.h:

#pragma once

#include <QWidget>

class QGridLayout;
class QPushButton;

class Widget : public QWidget
{
    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
private:
    void updateVisibility();
    QGridLayout *m_layout;
    QPushButton *m_button;
};

widget.cpp:

#include "widget.h"

#include <QGridLayout>
#include <QLabel>
#include <QPushButton>

Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    m_layout = new QGridLayout();
    m_layout->addWidget(new QLabel("Label1"), 0, 0);
    m_layout->addWidget(new QLabel("Label2"), 1, 0);

    m_button = new QPushButton("Visible");
    connect(m_button, &QPushButton::clicked, this, &Widget::updateVisibility);
    m_button->setCheckable(true);
    m_button->setChecked(false);

    auto layout = new QVBoxLayout(this);
    layout->addLayout(m_layout);
    layout->addWidget(m_button);
    updateVisibility();
}

void Widget::updateVisibility()
{
    // hide or show Label2
    m_layout->itemAtPosition(1, 0)->widget()->setVisible(m_button->isChecked());
    adjustSize();
}

Before:

enter image description here

After clicking 2 times on the button:

enter image description here

UPDATE: I reported this as a bug https://bugreports.qt.io/browse/QTBUG-66151 but I would like to find a suitable workaround until it is fixed.

1

1 Answers

1
votes

Cannot reproduce on Xubuntu 16.04.3 with Qt 5.5.1 or Qt 5.9.4. I do observe some strange behavior though. If I add Widget to a QMainWindow and check the button, it ignores the mainwindow's layout until the mainwindow is resized. If I use Widget as a top-level window, it becomes larger on the first click, and then never resizes again, unless the user changes the window size.

Possible workarounds:

  • Remove the adjustSize() call, that prevented my strange behavior.
  • Call update() on widget or it's parent after adjustSize() to schedule a redraw. (Cannot test since I have no drawing artefacts.)
  • Call m_layout->invalidate() after adjustSize() to schedule re-layouting. Fixes my problem when inside the mainwindow. You can also try that call on the widget's parent, or before adjustSize().