-
Bug
-
Resolution: Fixed
-
P1: Critical
-
5.15.18, 6.7.1
-
None
-
-
fa8bfd6ed (dev), fc84765ce (6.10), c1539406e (6.9), b2812290e (tqtc/lts-6.8), ee292d9c9 (tqtc/lts-6.5)
I'm having issues creating a custom `QtQuick.Controls.Container`. I've attached a minimal example of the component qml file. As far as I can tell from the docs, the design of the attached component is supported and idiomatic - please correct me if I've overlooked something!
The issue comes in dynamically removing items from this container.
If I call `container.removeItem(..)` I run into a crash in the QtQuick transition code - it seems like the container is deleting the items before the view has managed to apply the remove transition.
If I remove the items with simply `item.parent = null`, then they are correctly removed and animated off, but they are never freed. The memory hangs around until application exit. Obviously this isn't viable for production.
I have seen there is this `ListView.delayRemove` attached property for delegates and there's an example in the docs for dynamically changing this from `true` to `false` using `PropertyAction` animation. However, I fear this isn't viable for my proposed design since both the delegate and the transitions are injected by the consumer via the component api. And even if I set `ListView.delayRemove: true` on my delegate I still hit the crash on `container.removeItem(...)`.
Any help would be greatly appreciated!
import QtQuick import QtQuick.Controls ApplicationWindow { width: 640 height: 480 visible: true Column { anchors.fill: parent // transitions are customisable via the component api property alias displaced: view.displaced property alias add: view.add property alias remove: view.remove Container { id: container width: parent.width height: 200 contentItem: ListView { id: view model: container.contentModel spacing: 5 // example (normally such a transition would be injected by the client) displaced: Transition { NumberAnimation { properties: "y" duration: 100 } } } } Row { Button { text: "add" onClicked: { let item = component.createObject(container); item.width = width; container.addItem(item); } } Button { text: "remove" // Items are removed and animated off correctly, but never freed: // onClicked: { // let item = container.contentChildren[0]; // item.parent = null; // } // Crash in qtquick transition code: onClicked: { let item = container.contentChildren[0]; if (item) { container.removeItem(item); } } } } Component { id: component Rectangle { height: 50 color: "hotpink" Component.onCompleted: console.log("Construction!") Component.onDestruction: console.log("Destruction!") } } } }
For Gerrit Dashboard: QTBUG-133256 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
629802,23 | Fix heap-use-after-free in Container when using ListView transitions | dev | qt/qtdeclarative | Status: MERGED | +2 | 0 |
658602,2 | Fix heap-use-after-free in Container when using ListView transitions | 6.10 | qt/qtdeclarative | Status: MERGED | +2 | 0 |
658701,3 | Fix heap-use-after-free in Container when using ListView transitions | 6.9 | qt/qtdeclarative | Status: MERGED | +2 | 0 |
659932,4 | Fix heap-use-after-free in Container when using ListView transitions | tqtc/lts-6.8 | qt/tqtc-qtdeclarative | Status: MERGED | +2 | 0 |
667056,3 | Fix heap-use-after-free in Container when using ListView transitions | tqtc/lts-6.5 | qt/tqtc-qtdeclarative | Status: MERGED | +2 | 0 |