diff options
author | Joni Poikelin <joni.poikelin@qt.io> | 2016-07-20 10:21:08 +0300 |
---|---|---|
committer | Joni Poikelin <joni.poikelin@qt.io> | 2017-11-28 05:09:01 +0000 |
commit | 323fd0037c8d3e016c66fea024b57b11763624ed (patch) | |
tree | b23901e50c4834149a7c14d40ac02a27162666ba /tests/auto/quick | |
parent | 22858d41a5351e1bc3ffd9778af77643d90e395f (diff) |
Fix crash when moving items during asynchronous creation
In complicated cases where the model moves rows around while
the view is running slow (perhaps during high CPU load),
there were cases when Repeater would call
movedItem->stackBefore(deleteableItem), but deleteable items
can be null, so there was often an error
QQuickItem::stackBefore: Cannot stack before 0x0, which must be a sibling
and occasionally a crash. Now we check both the callee and the
parameter to stackBefore to make sure neither of them are null.
Task-number: QTBUG-54859
Change-Id: I45a8b2939c16b9bbe3a802ddd348dc55f51061a7
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'tests/auto/quick')
-rw-r--r-- | tests/auto/quick/qquickrepeater/data/asynchronousMove.qml | 51 | ||||
-rw-r--r-- | tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp | 25 |
2 files changed, 76 insertions, 0 deletions
diff --git a/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml b/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml new file mode 100644 index 0000000000..02499c8531 --- /dev/null +++ b/tests/auto/quick/qquickrepeater/data/asynchronousMove.qml @@ -0,0 +1,51 @@ +import QtQuick 2.3 +import QtQuick.Window 2.2 + +Item { + property bool finished: loader.status === Loader.Ready && loader.progress === 1 + + ListModel { + id: listModel + ListElement { i:0 } + ListElement { i:1 } + ListElement { i:2 } + ListElement { i:3 } + } + + Timer { + running: true + interval: 1 + repeat: count < 5 + property int count : 0 + + onTriggered: { + listModel.move(listModel.count - 1, listModel.count - 2, 1) + ++count + } + } + + Loader { + id: loader + asynchronous: true + sourceComponent: Row { + spacing: 4 + Repeater { + model: listModel + delegate: Column { + spacing: 4 + Repeater { + model: 4 + delegate: Rectangle { + width: 30 + height: 30 + color: "blue" + Component.onCompleted: { + ctrl.wait() + } + } + } + } + } + } + } +} diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp index f7b04e9a30..3519c53cb7 100644 --- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp +++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp @@ -75,6 +75,7 @@ private slots: void destroyCount(); void stackingOrder(); void objectModel(); + void QTBUG54859_asynchronousMove(); }; class TestObject : public QObject @@ -989,6 +990,30 @@ void tst_QQuickRepeater::objectModel() delete positioner; } +class Ctrl : public QObject +{ + Q_OBJECT +public: + + Q_INVOKABLE void wait() + { + QTest::qWait(200); + } +}; + +void tst_QQuickRepeater::QTBUG54859_asynchronousMove() +{ + Ctrl ctrl; + QQuickView* view = createView(); + view->rootContext()->setContextProperty("ctrl", &ctrl); + view->setSource(testFileUrl("asynchronousMove.qml")); + view->show(); + QQuickItem* item = view->rootObject(); + + + QTRY_COMPARE(item->property("finished"), QVariant(true)); +} + QTEST_MAIN(tst_QQuickRepeater) #include "tst_qquickrepeater.moc" |