Details
-
Suggestion
-
Resolution: Done
-
P3: Somewhat important
-
5.9.5
-
None
-
-
2b7edd053404f4819abf0203bb9c762799849638 (qt/qtbase/dev)
Description
I wanted to have a widget inside a layout replaced based on user input. The logic for that looked something like this:
qDebug() << layout.count(); // 1 (widget out of choosableWidget in layout) foreach ( widget, choosableWidgets ) { if ( layout.replaceWidget( widget, chosenWidget ) != 0 ) break; }
However, if chosenWidget is equal to the widget already in the layout, then replaceWidget effectively removes the widget instead of leaving it untouched. I find this behavior to be undocumented and unintuitive.
Here is a minimal bug-reproducing example which made me realize, that the behavior depends on whether the layout is being used by a widget or not, which makes this even weirder:
#include <QApplication> #include <QWidget> #include <QVBoxLayout> #include <QDebug> int main(int argc, char *argv[]) { QApplication app( argc, argv ); auto const layout = new QVBoxLayout(); auto const widget = new QWidget(); layout->addWidget( widget ); #define BUG #ifdef BUG auto const treeBox = new QWidget(); treeBox->setLayout( layout ); #endif qDebug() << layout->count(); // output: 1 layout->replaceWidget( widget, widget, Qt::FindDirectChildrenOnly ); qDebug() << layout->count(); // output: 0 if BUG defined else 1 ! }