I have a piece of code which does this: a method named prepareUI
makes the UI ready to be able to load search results that are fed into it. A method named onClear
that is called when the results that are already showing needs to be cleared. And a method named populateSearchResults
that takes the search data and loads the UI with it. The container that holds the data is a publicly available pointer, since it is needed to clear the results from onClear
:
void MyClass::prepareSearchUI() {
//there may be many search results, hence need a scroll view to hold them
fResultsViewBox = new QScrollArea(this);
fResultsViewBox->setGeometry(28,169,224,232);
fSearchResultsLayout = new QGridLayout();
}
void MyClass::onClear() {
//I have tried this, this causes the problem, even though it clears the data correctly
delete fSearchResultContainer;
//tried this, does nothing
QLayoutItem *child;
while ((child = fSearchResultsLayout->takeAt(0)) != 0) {
...
delete child;
}
}
void MyClass::populateWithSearchesults(std::vector<std::string> &aSearchItems) {
fSearchResultContainer = new QWidget();
fSearchResultContainer->setLayout(fSearchResultsLayout);
for (int rowNum = 0; rowNum < aSearchItems.size(); rowNum++) {
QHBoxLayout *row = new QHBoxLayout();
//populate the row with some widgets, all allocated through 'new', without specifying any parent, like
QPushButton *loc = new QPushButton("Foo");
row->addWidget(loc);
fSearchResultsLayout->addLayout(row, rowNum, 0,1,2);
}
fResultsViewBox->setWidget(fSearchResultContainer);
}
Problem is, when I call onClear
which internally calls delete
, it does remove all the results that were showing. But after that, if I call populateWithSearchesults
again, my app crashes, and the stack trace shows this method as where it crashed.
How do I fix this problem?
It seems that you have some misconceptions about ownership. A QLayout
takes ownership of any item that is added to it: http://doc.qt.io/qt-5/qlayout.html#addItem
That means the QLayout
is responsible for deleting these items. If you delete them then the QLayout
will also try to delete them and then you get the crash you're seeing now.
QLayout
doesn't have good functionality for deleting contents and re-adding them (for example removeWidget
probably doesn't work as you would hope.) But there's a reason for this.
QLayout
is not intended to be used as a list view.
What you do want is a, wait for it, QListView
. Which will even handle the scroll functionality for you, and make adding and removing elements a possibility.