Reputation: 5223
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?
Upvotes: 3
Views: 7516
Reputation: 4579
Actually you can solve this issue easily, even if you are using QGridLayout
or any other Layout
s :
subLayout->removeWidget(m_visibleCheckBox);//removes and then it causes some zigzag drawing at (0,0)
m_visibleCheckBox->setVisible(false);//asks to redraw the component internally
setLayout(subLayout);//for safety as we may use that layout again and again
If you just use the first line it will cause this :
Upvotes: 0
Reputation: 38959
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.
Upvotes: 4