Controls2 StackView and destroyOnPop
-
Hello.
I have application which uses StackView and pushes a lot of dynamic created objects into this StackView and I need some way to destroy this objecst when they are popped from StackView. If I use Controls 1 Stackview, I can just push object with destroyOnPop property:tablesStack.push({item: view, destroyOnPop: true})
but it doesn't applicable to Controls 2 StackView. What is correct solution of this problem?
I know only one way: call object.destroy() with delay when I pop it, but this way looks like kludge. If it is important, I can add any code to dynamic generated objects
-
Controls 2 StackView has simplified ownership semantics. StackView takes ownership of any item that it has dynamically instantiated. If you have created the instance, then you're in control of the instance. In other words, if you want StackView to destroy, push Components or URLs and let StackView create the instances.
-
http://stackoverflow.com/questions/39063235/qtquick-controls-2-stackview-and-destroyonpop -here is our with jpnurmi discussion at stackoverflow, maybe it will usefull for someone also
-
Hi again. I found way to cause crash if I use Qt.createComponent + createObject + FileDialog +Controls2.StackView. Here is my code:
Main.qml (for this example I just create qml app from QtCreator template and rewrite main.qml)
import QtQuick 2.7 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.0 ApplicationWindow { id: window visible: true height: 300 ColumnLayout{ Button { text: "Push" onClicked: { var component = Qt.createComponent("file:///D:/aknew-Data/Sandbox/build-test-Desktop_Qt_5_7_0_MinGW_32bit-Debug/debug/TestQML.qml") switch (component.status) { case Component.Ready: var form = component.createObject() stackView.push(form) break case Component.Error: console.log(component.errorString()) break } } } Button { text: "Pop" onClicked: stackView.pop() } StackView { id: stackView height: 100 width: 100 initialItem: Rectangle { Component.onDestruction: console.log( "Cyan Destruction Beginning!") color: "cyan" } } } }
TestQml which I loadfrom file:
import QtQuick 2.5 import QtQuick.Controls 2.0 import QtQuick.Dialogs 1.2 Rectangle { Component.onDestruction: console.log("Green Destruction Beginning!") color: "Green" FileDialog {} }
If I push-pop TestQml few times, I got QCoreApplication::postEvent: Unexpected null receiver during push (really during component.createObject() ) and app crashes. It seems that reason is that js garbage collector destroy previous instances of component , but something in C++ still have pointer to it (I suppose so because I have seen some methods with name like QV4::MemoryManager::runGC in call stack when I tried to debug this crash, but it happens rarely with active debugger and doesn't happen if I make push-pop sequence from code). I figure out that if I remove FileDialog, the app does not crash.
I understand that my code can be incorrect for Controls 2, but I haven't had any system notification about it, this code is result of migration from Controls 1 and it is work in general (when I don't use FileDialog), so I think this situation is should be at least described because figure out what causes this crash was not easy
My environment is Qt Creator 4.0.2, Qt 5.7.0, MinGW 32 bit, OS Win 8.1 64 bit, if you need some other information, please, I ready to answer, but maybe not very fast - I use qt only in my pet project now.