C++11: Yes!
C++11 and onwards has this same feature (called delegating constructors).
The syntax is slightly different from C#:
class Foo {
public:
Foo(char x, int y) {}
Foo(int y) : Foo('a', y) {}
};
C++03: No
Unfortunately, there's no way to do this in C++03, but there are two ways of simulating this:
You can combine two (or more) constructors via default parameters:
class Foo {
public:
Foo(char x, int y=0); // combines two constructors (char) and (char, int)
// ...
};
Use an init method to share common code:
class Foo {
public:
Foo(char x);
Foo(char x, int y);
// ...
private:
void init(char x, int y);
};
Foo::Foo(char x)
{
init(x, int(x) + 7);
// ...
}
Foo::Foo(char x, int y)
{
init(x, y);
// ...
}
void Foo::init(char x, int y)
{
// ...
}
See the C++FAQ entry for reference.
Short answer: Use the code provided below
Removing a row or column (or even a single cell) from a QGridLayout
is tricky. Use the code provided below.
Long answer: Digging into QGridLayout details
First, note that QGridLayout::rowCount()
and QGridLayout::columnCount()
always return the number of internally allocated rows and columns in the grid layout. As an example, if you call QGridLayout::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 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 (or cell) 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 contents but still have to be taken care of.
The code
#include <QGridLayout>
#include <QWidget>
/**
* Utility class to remove the contents of a QGridLayout row, column or
* cell. If the deleteWidgets parameter is true, then the widgets become
* not only removed from the layout, but also deleted. Note that we won't
* actually remove any row or column itself from the layout, as this isn't
* possible. So the rowCount() and columnCount() will always stay the same,
* but the contents of the row, column or cell will be removed.
*/
class GridLayoutUtil {
public:
// Removes the contents of the given layout row.
static void removeRow(QGridLayout *layout, int row, bool deleteWidgets = true) {
remove(layout, row, -1, deleteWidgets);
layout->setRowMinimumHeight(row, 0);
layout->setRowStretch(row, 0);
}
// Removes the contents of the given layout column.
static void removeColumn(QGridLayout *layout, int column, bool deleteWidgets = true) {
remove(layout, -1, column, deleteWidgets);
layout->setColumnMinimumWidth(column, 0);
layout->setColumnStretch(column, 0);
}
// Removes the contents of the given layout cell.
static void removeCell(QGridLayout *layout, int row, int column, bool deleteWidgets = true) {
remove(layout, row, column, deleteWidgets);
}
private:
// Removes all layout items which span the given row and column.
static void remove(QGridLayout *layout, int row, int column, bool deleteWidgets) {
// We avoid usage of QGridLayout::itemAtPosition() here to improve performance.
for (int i = layout->count() - 1; i >= 0; i--) {
int r, c, rs, cs;
layout->getItemPosition(i, &r, &c, &rs, &cs);
if (
(row == -1 || (r <= row && r + rs > row)) &&
(column == -1 || (c <= column && c + cs > column))) {
// This layout item is subject to deletion.
QLayoutItem *item = layout->takeAt(i);
if (deleteWidgets) {
deleteChildWidgets(item);
}
delete item;
}
}
}
// Deletes all child widgets of the given layout item.
static void deleteChildWidgets(QLayoutItem *item) {
QLayout *layout = item->layout();
if (layout) {
// Process all child items recursively.
int itemCount = layout->count();
for (int i = 0; i < itemCount; i++) {
deleteChildWidgets(layout->itemAt(i));
}
}
delete item->widget();
}
};
Best Answer
Just to be clear. You didn't "delete" the widgets. You only removed them from layout. Removing from layout means only that widget will be no more managed (resized/positioned) by this layout BUT it doesn't mean that widget will be "deleted" (in C++ way). Also widget won't be magically hidden. Your widget after removing from layout still leaves in widget it was created / managed in. So owner of this layout still has this widget as child (visible child).
You have to
hide widget or if you're sure it will not be used anymore
delete widget with "delete" keyword
Also you don't need to call
removeWidget(item->widget())
;removeItem(item)
will be enough for all layout items (even those with widget inside)