Skip to content

Commit c0688f4

Browse files
Jan Arve SaetherThe Qt Project
Jan Arve Saether
authored and
The Qt Project
committed
Fixed QLayout::addChildLayout(QLayout *l) when l had a parent
Previously if l had a parent, addChildLayout would warn and skip the reparenting, but it would still add the sub layout to the layout. This caused some inconsistencies in the hierarchy which in worst case could cause crashes. Task-number: QTBUG-30758 (cherry-picked from qtbase commit 146658a10f290603470b800d71b778239e764312) Change-Id: Iee6ace3189620395d7670007a23783823ed616b9 Reviewed-by: Paul Olav Tvete <[email protected]>
1 parent 17f2639 commit c0688f4

File tree

6 files changed

+40
-5
lines changed

6 files changed

+40
-5
lines changed

src/gui/kernel/qboxlayout.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,8 @@ void QBoxLayout::insertSpacerItem(int index, QSpacerItem *spacerItem)
10011001
void QBoxLayout::insertLayout(int index, QLayout *layout, int stretch)
10021002
{
10031003
Q_D(QBoxLayout);
1004-
addChildLayout(layout);
1004+
if (!adoptLayout(layout))
1005+
return;
10051006
if (index < 0) // append
10061007
index = d->list.count();
10071008
QBoxLayoutItem *it = new QBoxLayoutItem(layout, stretch);

src/gui/kernel/qformlayout.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -976,8 +976,8 @@ void QFormLayoutPrivate::setLayout(int row, QFormLayout::ItemRole role, QLayout
976976
{
977977
if (layout) {
978978
Q_Q(QFormLayout);
979-
q->addChildLayout(layout);
980-
setItem(row, role, layout);
979+
if (q->adoptLayout(layout))
980+
setItem(row, role, layout);
981981
}
982982
}
983983

src/gui/kernel/qgridlayout.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,7 +1609,8 @@ void QGridLayout::addWidget(QWidget *widget, int fromRow, int fromColumn,
16091609
void QGridLayout::addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment)
16101610
{
16111611
Q_D(QGridLayout);
1612-
addChildLayout(layout);
1612+
if (!adoptLayout(layout))
1613+
return;
16131614
QGridBox *b = new QGridBox(layout);
16141615
b->setAlignment(alignment);
16151616
d->add(b, row, column);
@@ -1628,7 +1629,8 @@ void QGridLayout::addLayout(QLayout *layout, int row, int column,
16281629
int rowSpan, int columnSpan, Qt::Alignment alignment)
16291630
{
16301631
Q_D(QGridLayout);
1631-
addChildLayout(layout);
1632+
if (!adoptLayout(layout))
1633+
return;
16321634
QGridBox *b = new QGridBox(layout);
16331635
b->setAlignment(alignment);
16341636
d->add(b, row, (rowSpan < 0) ? -1 : row + rowSpan - 1, column, (columnSpan < 0) ? -1 : column + columnSpan - 1);

src/gui/kernel/qlayout.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,16 @@ void QLayout::addChildLayout(QLayout *l)
935935

936936
}
937937

938+
/*!
939+
\internal
940+
*/
941+
bool QLayout::adoptLayout(QLayout *layout)
942+
{
943+
const bool ok = !layout->parent();
944+
addChildLayout(layout);
945+
return ok;
946+
}
947+
938948
#ifdef QT_DEBUG
939949
static bool layoutDebug()
940950
{

src/gui/kernel/qlayout.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ class Q_GUI_EXPORT QLayout : public QObject, public QLayoutItem
189189
void childEvent(QChildEvent *e);
190190
void addChildLayout(QLayout *l);
191191
void addChildWidget(QWidget *w);
192+
bool adoptLayout(QLayout *layout);
192193
#ifdef QT3_SUPPORT
193194
QT3_SUPPORT void deleteAllItems();
194195
#endif

tests/auto/qboxlayout/tst_qboxlayout.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public slots:
6262

6363
private slots:
6464
void insertSpacerItem();
65+
void insertLayout();
6566
void sizeHint();
6667
void sizeConstraints();
6768
void setGeometry();
@@ -160,6 +161,26 @@ void tst_QBoxLayout::insertSpacerItem()
160161
window->show();
161162
}
162163

164+
void tst_QBoxLayout::insertLayout()
165+
{
166+
QWidget *window = new QWidget;
167+
QVBoxLayout *vbox = new QVBoxLayout(window);
168+
QVBoxLayout *dummyParentLayout = new QVBoxLayout;
169+
QHBoxLayout *subLayout = new QHBoxLayout;
170+
dummyParentLayout->addLayout(subLayout);
171+
QCOMPARE(subLayout->parent(), dummyParentLayout);
172+
QCOMPARE(dummyParentLayout->count(), 1);
173+
174+
// add subLayout to another layout
175+
QTest::ignoreMessage(QtWarningMsg, "QLayout::addChildLayout: layout \"\" already has a parent");
176+
vbox->addLayout(subLayout);
177+
QCOMPARE((subLayout->parent() == vbox), (vbox->count() == 1));
178+
179+
delete dummyParentLayout;
180+
delete window;
181+
}
182+
183+
163184
void tst_QBoxLayout::sizeHint()
164185
{
165186
QWidget *window = new QWidget;

0 commit comments

Comments
 (0)