[QTBUG-27420] Make Q{Box,Grid,Form}Layout::takeAt() unparent a nested layout
QStackedLayout doesn't have support for QLayout, only QWidget, so the issue doesn't arise there. Reported-by: Johannes Schaub Task-number: QTBUG-27420 Change-Id: I71f8d10a036918c16d8f8c9197a2ec61cd76cf01 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
parent
1211b956de
commit
716d33d2a7
@ -729,6 +729,12 @@ QLayoutItem *QBoxLayout::takeAt(int index)
|
|||||||
b->item = 0;
|
b->item = 0;
|
||||||
delete b;
|
delete b;
|
||||||
|
|
||||||
|
if (QLayout *l = item->layout()) {
|
||||||
|
// sanity check in case the user passed something weird to QObject::setParent()
|
||||||
|
if (l->parent() == this)
|
||||||
|
l->setParent(0);
|
||||||
|
}
|
||||||
|
|
||||||
invalidate();
|
invalidate();
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
@ -1409,6 +1409,13 @@ QLayoutItem *QFormLayout::takeAt(int index)
|
|||||||
QLayoutItem *i = item->item;
|
QLayoutItem *i = item->item;
|
||||||
item->item = 0;
|
item->item = 0;
|
||||||
delete item;
|
delete item;
|
||||||
|
|
||||||
|
if (QLayout *l = i->layout()) {
|
||||||
|
// sanity check in case the user passed something weird to QObject::setParent()
|
||||||
|
if (l->parent() == this)
|
||||||
|
l->setParent(0);
|
||||||
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,15 +156,20 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inline QLayoutItem *takeAt(int index) {
|
inline QLayoutItem *takeAt(int index) {
|
||||||
QLayoutItem *item = 0;
|
Q_Q(QGridLayout);
|
||||||
if (index < things.count()) {
|
if (index < things.count()) {
|
||||||
QGridBox *b = things.takeAt(index);
|
if (QGridBox *b = things.takeAt(index)) {
|
||||||
if (b) {
|
QLayoutItem *item = b->takeItem();
|
||||||
item = b->takeItem();
|
if (QLayout *l = item->layout()) {
|
||||||
|
// sanity check in case the user passed something weird to QObject::setParent()
|
||||||
|
if (l->parent() == q)
|
||||||
|
l->setParent(0);
|
||||||
|
}
|
||||||
delete b;
|
delete b;
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan) const {
|
void getItemPosition(int index, int *row, int *column, int *rowSpan, int *columnSpan) const {
|
||||||
|
@ -66,6 +66,7 @@ private slots:
|
|||||||
void setStyleShouldChangeSpacing();
|
void setStyleShouldChangeSpacing();
|
||||||
|
|
||||||
void taskQTBUG_7103_minMaxWidthNotRespected();
|
void taskQTBUG_7103_minMaxWidthNotRespected();
|
||||||
|
void taskQTBUG_27420_takeAtShouldUnparentLayout();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CustomLayoutStyle : public QProxyStyle
|
class CustomLayoutStyle : public QProxyStyle
|
||||||
@ -273,5 +274,26 @@ void tst_QBoxLayout::taskQTBUG_7103_minMaxWidthNotRespected()
|
|||||||
QCOMPARE(label->height(), height);
|
QCOMPARE(label->height(), height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QBoxLayout::taskQTBUG_27420_takeAtShouldUnparentLayout()
|
||||||
|
{
|
||||||
|
QSharedPointer<QHBoxLayout> outer(new QHBoxLayout);
|
||||||
|
QPointer<QVBoxLayout> inner = new QVBoxLayout;
|
||||||
|
|
||||||
|
outer->addLayout(inner);
|
||||||
|
QCOMPARE(outer->count(), 1);
|
||||||
|
QCOMPARE(inner->parent(), outer.data());
|
||||||
|
|
||||||
|
QLayoutItem *item = outer->takeAt(0);
|
||||||
|
QCOMPARE(item->layout(), inner.data());
|
||||||
|
QVERIFY(!item->layout()->parent());
|
||||||
|
|
||||||
|
outer.reset();
|
||||||
|
|
||||||
|
if (inner)
|
||||||
|
delete item; // success: a taken item/layout should not be deleted when the old parent is deleted
|
||||||
|
else
|
||||||
|
QVERIFY(!inner.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QBoxLayout)
|
QTEST_MAIN(tst_QBoxLayout)
|
||||||
#include "tst_qboxlayout.moc"
|
#include "tst_qboxlayout.moc"
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include <QtWidgets/QLineEdit>
|
#include <QtWidgets/QLineEdit>
|
||||||
#include <QtWidgets/QPushButton>
|
#include <QtWidgets/QPushButton>
|
||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
#include <qformlayout.h>
|
#include <qformlayout.h>
|
||||||
|
|
||||||
@ -123,6 +124,8 @@ private slots:
|
|||||||
Qt::Orientations expandingDirections() const;
|
Qt::Orientations expandingDirections() const;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
void taskQTBUG_27420_takeAtShouldUnparentLayout();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tst_QFormLayout::tst_QFormLayout()
|
tst_QFormLayout::tst_QFormLayout()
|
||||||
@ -901,6 +904,27 @@ void tst_QFormLayout::layoutAlone()
|
|||||||
QTest::qWait(500);
|
QTest::qWait(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QFormLayout::taskQTBUG_27420_takeAtShouldUnparentLayout()
|
||||||
|
{
|
||||||
|
QSharedPointer<QFormLayout> outer(new QFormLayout);
|
||||||
|
QPointer<QFormLayout> inner = new QFormLayout;
|
||||||
|
|
||||||
|
outer->addRow(inner);
|
||||||
|
QCOMPARE(outer->count(), 1);
|
||||||
|
QCOMPARE(inner->parent(), outer.data());
|
||||||
|
|
||||||
|
QLayoutItem *item = outer->takeAt(0);
|
||||||
|
QCOMPARE(item->layout(), inner.data());
|
||||||
|
QVERIFY(!item->layout()->parent());
|
||||||
|
|
||||||
|
outer.reset();
|
||||||
|
|
||||||
|
if (inner)
|
||||||
|
delete item; // success: a taken item/layout should not be deleted when the old parent is deleted
|
||||||
|
else
|
||||||
|
QVERIFY(!inner.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QFormLayout)
|
QTEST_MAIN(tst_QFormLayout)
|
||||||
|
|
||||||
#include "tst_qformlayout.moc"
|
#include "tst_qformlayout.moc"
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include <QtWidgets/QLineEdit>
|
#include <QtWidgets/QLineEdit>
|
||||||
#include <QtWidgets/QRadioButton>
|
#include <QtWidgets/QRadioButton>
|
||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
class tst_QGridLayout : public QObject
|
class tst_QGridLayout : public QObject
|
||||||
{
|
{
|
||||||
@ -89,6 +90,8 @@ private slots:
|
|||||||
void contentsRect();
|
void contentsRect();
|
||||||
void distributeMultiCell();
|
void distributeMultiCell();
|
||||||
|
|
||||||
|
void taskQTBUG_27420_takeAtShouldUnparentLayout();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget *testWidget;
|
QWidget *testWidget;
|
||||||
QGridLayout *testLayout;
|
QGridLayout *testLayout;
|
||||||
@ -1605,5 +1608,26 @@ void tst_QGridLayout::distributeMultiCell()
|
|||||||
QCOMPARE(w.sizeHint().height(), 11 + 57 + 11);
|
QCOMPARE(w.sizeHint().height(), 11 + 57 + 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QGridLayout::taskQTBUG_27420_takeAtShouldUnparentLayout()
|
||||||
|
{
|
||||||
|
QSharedPointer<QGridLayout> outer(new QGridLayout);
|
||||||
|
QPointer<QGridLayout> inner = new QGridLayout;
|
||||||
|
|
||||||
|
outer->addLayout(inner, 0, 0);
|
||||||
|
QCOMPARE(outer->count(), 1);
|
||||||
|
QCOMPARE(inner->parent(), outer.data());
|
||||||
|
|
||||||
|
QLayoutItem *item = outer->takeAt(0);
|
||||||
|
QCOMPARE(item->layout(), inner.data());
|
||||||
|
QVERIFY(!item->layout()->parent());
|
||||||
|
|
||||||
|
outer.reset();
|
||||||
|
|
||||||
|
if (inner)
|
||||||
|
delete item; // success: a taken item/layout should not be deleted when the old parent is deleted
|
||||||
|
else
|
||||||
|
QVERIFY(!inner.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_QGridLayout)
|
QTEST_MAIN(tst_QGridLayout)
|
||||||
#include "tst_qgridlayout.moc"
|
#include "tst_qgridlayout.moc"
|
||||||
|
Loading…
Reference in New Issue
Block a user