I have this code:
QVariant componentFromCode(QString code) {
QQmlComponent * component = new QQmlComponent(engine);
engine->setObjectOwnership(component, QQmlEngine::JavaScriptOwnership);
connect(component, &QQmlComponent::destroyed, this, &Factory::echo);
component->setData(code.toUtf8(), QUrl());
return QVariant::fromValue(component);
}
But Factory::echo()
is never called, which means the object gets leaked every time the function is called.
This is what I have on the QML side:
onClicked: {
var code =
'import QtQuick 2.3
Rectangle {
width: 50
height: 50
color: "blue"
}
'
stack.push(Factory.componentFromCode(code))
gc()
}
I explicitly set the object ownership, and explicitly call gc()
to force garbage collection, but the destroyed()
signal never gets emitted, therefore the object never gets deleted. From what I read this is supposed to happen automatically in QML.
Note that it works to:
var comp = Factory.componentFromCode(code)
stack.push(comp)
comp.destroy()
But it is just not convenient, I'd like to have the object destroyed automatically as it falls out of scope, or alternatively, remain alive for as long as it is referenced by QML code and be destroyed when it is no longer needed, something that might be hard/absurd to do manually in many situations.
EDIT: The stack example happened to be my actual code, but I guess it is not that good of an example, seeing how the stack taking ownership over the component is assumed. I don't get any lifetime management even in such simple cases as:
function JSfoo() {
var obj = CXTProp.getCppQObjectStar()
console.log(obj.objectName)
} // QObject is not collected here
or...
QtObject {
property QtObject: CXTProp.getCppQObjectStar()
} // QObject is not collected after the object is destroyed