Hello,
I created a scroll area and called setWidget() to set the "inner" widget. The inner widget has a layout that I want to clear from time to time. In the documentation for QLayout::takeAt() I found this:
http://doc.trolltech.com/4.5/qlayout.html#takeAt
Unfortunately, it does not work (it looks like a redraw problem). What works is keeping a separate list of added widgets, and deleting them manually. I can't understand what's going on. I'm posting a complete test class showing the problem:
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QScrollArea>
#include <QLabel>
#include <QList>
class ScrollAreaTest
: public QWidget{
Q_OBJECT
public:
ScrollAreaTest
(QWidget* parent
= 0): {
// buttons
connect(btnAdd, SIGNAL(clicked()), this, SLOT(onBtnAdd()));
connect(btnClear1, SIGNAL(clicked()), this, SLOT(onBtnClear1()));
connect(btnClear2, SIGNAL(clicked()), this, SLOT(onBtnClear2()));
// scroll area
myScrollArea->setWidgetResizable(true);
myScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
myScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
// scroll area "inner" widget
innerWidget->setLayout(innerWidgetLayout);
// set scroll area inner widget
myScrollArea->setWidget(innerWidget);
// main layout
layout->addWidget(btnAdd);
layout->addWidget(btnClear1);
layout->addWidget(btnClear2);
layout->addWidget(myScrollArea);
setLayout(layout);
}
private:
QList<QLabel*> addedLabels;
private slots:
void onBtnAdd()
{
innerWidgetLayout->addWidget(l);
addedLabels.push_back(l); // I'm keeping a list of added labels (see onBtnClear2)
}
void onBtnClear1() // this is from the docs and doesn't work
{
while ((child = innerWidgetLayout->takeAt(0)) != 0)
delete child;
/*
innerWidgetLayout->activate();
innerWidgetLayout->update();
update();
*/
}
void onBtnClear2() // this works
{
for (QList<QLabel*>::iterator it = addedLabels.begin(); it != addedLabels.end(); ++it)
delete *it;
addedLabels.clear();
}
};
#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>
#include <QScrollArea>
#include <QLabel>
#include <QList>
class ScrollAreaTest : public QWidget
{
Q_OBJECT
public:
ScrollAreaTest(QWidget* parent = 0):
QWidget(parent)
{
// buttons
QPushButton* btnAdd = new QPushButton("Add label");
connect(btnAdd, SIGNAL(clicked()), this, SLOT(onBtnAdd()));
QPushButton* btnClear1 = new QPushButton("Clear Layout (mode 1)");
connect(btnClear1, SIGNAL(clicked()), this, SLOT(onBtnClear1()));
QPushButton* btnClear2 = new QPushButton("Clear Layout (mode 2)");
connect(btnClear2, SIGNAL(clicked()), this, SLOT(onBtnClear2()));
// scroll area
QScrollArea* myScrollArea = new QScrollArea();
myScrollArea->setWidgetResizable(true);
myScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
myScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
// scroll area "inner" widget
QWidget* innerWidget = new QWidget();
innerWidgetLayout = new QVBoxLayout();
innerWidget->setLayout(innerWidgetLayout);
// set scroll area inner widget
myScrollArea->setWidget(innerWidget);
// main layout
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(btnAdd);
layout->addWidget(btnClear1);
layout->addWidget(btnClear2);
layout->addWidget(myScrollArea);
setLayout(layout);
}
private:
QVBoxLayout* innerWidgetLayout;
QList<QLabel*> addedLabels;
private slots:
void onBtnAdd()
{
QLabel* l = new QLabel("Hello there!");
innerWidgetLayout->addWidget(l);
addedLabels.push_back(l); // I'm keeping a list of added labels (see onBtnClear2)
}
void onBtnClear1() // this is from the docs and doesn't work
{
QLayoutItem *child;
while ((child = innerWidgetLayout->takeAt(0)) != 0)
delete child;
/*
innerWidgetLayout->activate();
innerWidgetLayout->update();
update();
*/
}
void onBtnClear2() // this works
{
for (QList<QLabel*>::iterator it = addedLabels.begin(); it != addedLabels.end(); ++it)
delete *it;
addedLabels.clear();
}
};
To copy to clipboard, switch view to plain text mode
Thank you
Bookmarks