I try to remove widgets from a specified row in a QGridLayout
like this:
void delete_grid_row(QGridLayout *layout, int row)
{
if (!layout || row < 0) return;
for (int i = 0; i < layout->columnCount(); ++i) {
QLayoutItem* item = layout->itemAtPosition(row, i);
if (!item) continue;
if (item->widget()) {
layout->removeWidget(item->widget());
} else {
layout->removeItem(item);
}
delete item;
}
}
But when I call it, the app crashes with SIGSEGV on delete item
in the first iteration. Any ideas?
The
QGridLayout
itself is managing theQLayoutItem
's. I believe the moment you callremoveWidget
the item will be deleted. Thus you have an invalid pointer at that point. Attempting to do anything with it, not justdelete
, will fail.Thus, just don't delete it, you'll be fine.
Short answer: Use the code provided below
Removing a row or column from a
QGridLayout
is tricky. Use theremoveRow()
andremoveColumn()
functions from the code provided below.Long answer: Digging into QGridLayout details
First, note that
QGridLayout::rowCount()
andQGridLayout::columnCount()
always return the number of internally allocated rows and columns in the grid layout. As an example, if you callQGridLayout::addWidget(widget,5,7)
on a freshly constructed grid layout, the row count will be 6 and the column count will be 8, and all cells of the grid layout except the cell on index (5,7) will be empty and thus invisible within the GUI.Note that it's unfortunately impossible to remove such an internal row or column from the grid layout. In other words, the row and column count of a grid layout can always only grow, but never shrink.
What you can do is to remove the cell contents of a row or column, which will effectively have the same visual effect as removing the row or column itself. But this of course means that all row and column counts and indices will remain unchanged.
So how can the contents of a row or column be cleared? This unfortunately also isn't as easy as it might seem.
First, you need to think about if you only want to remove the widgets from the layout, or if you also want them to become deleted. If you only remove the widgets from the layout, you must put them back into a different layout afterwards or manually give them a reasonable geometry. If the widgets also become deleted, they will disappear from the GUI. The provided code uses a boolean parameter to control widget deletion.
Next, you have to consider that a layout cell can not just only contain a widget, but also a nested layout, which itself can contain nested layouts, and so on. You further need to handle layout items which span over multiple rows and columns. And, finally, there are some row and column attributes like minimum widths and heights which don't depend on the actual cell contents but still have to be taken care of.
The code
Use
removeRow()
andremoveColumn()
to remove a row or column from a givenQGridLayout
.