diff --git a/src/gui/itemmodels/qstandarditemmodel.cpp b/src/gui/itemmodels/qstandarditemmodel.cpp index 64ffdaa3b7..be798f578f 100644 --- a/src/gui/itemmodels/qstandarditemmodel.cpp +++ b/src/gui/itemmodels/qstandarditemmodel.cpp @@ -1858,28 +1858,30 @@ QStandardItem *QStandardItem::takeChild(int row, int column) if (index != -1) { QModelIndex changedIdx; item = d->children.at(index); - if (item && d->model) { + if (item) { QStandardItemPrivate *const item_d = item->d_func(); - const int savedRows = item_d->rows; - const int savedCols = item_d->columns; - const QVector savedChildren = item_d->children; - if (savedRows > 0) { - d->model->d_func()->rowsAboutToBeRemoved(item, 0, savedRows - 1); - item_d->rows = 0; - item_d->children = QVector(); //slightly faster than clear - d->model->d_func()->rowsRemoved(item, 0, savedRows); - } - if (savedCols > 0) { - d->model->d_func()->columnsAboutToBeRemoved(item, 0, savedCols - 1); - item_d->columns = 0; - if (!item_d->children.isEmpty()) + if (d->model) { + QStandardItemModelPrivate *const model_d = d->model->d_func(); + const int savedRows = item_d->rows; + const int savedCols = item_d->columns; + const QVector savedChildren = item_d->children; + if (savedRows > 0) { + model_d->rowsAboutToBeRemoved(item, 0, savedRows - 1); + item_d->rows = 0; item_d->children = QVector(); //slightly faster than clear - d->model->d_func()->columnsRemoved(item, 0, savedCols); + model_d->rowsRemoved(item, 0, savedRows); + } + if (savedCols > 0) { + model_d->columnsAboutToBeRemoved(item, 0, savedCols - 1); + item_d->columns = 0; + item_d->children = QVector(); //slightly faster than clear + model_d->columnsRemoved(item, 0, savedCols); + } + item_d->rows = savedRows; + item_d->columns = savedCols; + item_d->children = savedChildren; + changedIdx = d->model->indexFromItem(item); } - item_d->rows = savedRows; - item_d->columns = savedCols; - item_d->children = savedChildren; - changedIdx = d->model->indexFromItem(item); item_d->setParentAndModel(nullptr, nullptr); } d->children.replace(index, nullptr); diff --git a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp index f5f02761d5..7489b7bf13 100644 --- a/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp +++ b/tests/auto/gui/itemmodels/qstandarditemmodel/tst_qstandarditemmodel.cpp @@ -120,6 +120,7 @@ private slots: void taskQTBUG_45114_setItemData(); void setItemPersistentIndex(); void signalsOnTakeItem(); + void takeChild(); void createPersistentOnLayoutAboutToBeChanged(); private: QStandardItemModel *m_model = nullptr; @@ -1828,5 +1829,36 @@ void tst_QStandardItemModel::createPersistentOnLayoutAboutToBeChanged() // QTBUG QCOMPARE(layoutChangedSpy.size(), 1); } +void tst_QStandardItemModel::takeChild() // QTBUG-117900 +{ + { + // with model + QStandardItemModel model1; + QStandardItemModel model2; + QStandardItem base1("base1"); + model1.setItem(0, 0, &base1); + QStandardItem base2("base2"); + model2.setItem(0, 0, &base2); + auto item = new QStandardItem("item1"); + item->appendRow({new QStandardItem("child")}); + base1.appendRow({item}); + base2.appendRow({base1.takeChild(0, 0)}); + QCOMPARE(base1.child(0, 0), nullptr); + QCOMPARE(base2.child(0, 0), item); + } + { + // without model + QStandardItem base1("base1"); + QStandardItem base2("base2"); + auto item = new QStandardItem("item1"); + item->appendRow({new QStandardItem("child")}); + base1.appendRow({item}); + base2.appendRow({base1.takeChild(0, 0)}); + QCOMPARE(base1.child(0, 0), nullptr); + QCOMPARE(base2.child(0, 0), item); + } +} + + QTEST_MAIN(tst_QStandardItemModel) #include "tst_qstandarditemmodel.moc"