How to control the lifetime of a dynamically allocated QObject returned in QML?

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 it is Factory::echo()never called, which means that the object leaks 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 establish the ownership of the object and explicitly call gc()to force garbage collection, but the signal is destroyed()never emitted, so the object is never deleted. From what I read, this should happen automatically in QML.

Please note that it works with:

var comp = Factory.componentFromCode(code)
stack.push(comp)
comp.destroy()

, , , , , , , QML , , / .

EDIT: , , , , , . , :

function JSfoo() {
    var obj = CXTProp.getCppQObjectStar()
    console.log(obj.objectName)
} // QObject is not collected here

...

QtObject {
    property QtObject: CXTProp.getCppQObjectStar()
} // QObject is not collected after the object is destroyed
+3
1

, . :

class TestObj : public QObject {
     Q_OBJECT
public:
    ~TestObj() { qDebug() << "destructor called"; }
};

class Test : public QObject {
    Q_OBJECT
public:
    explicit Test(QObject *parent = 0) : QObject(parent) {}
public slots:
    QVariant getObject() {
        QObject * obj = new TestObj;
        obj->setObjectName("that object");
        connect (obj, &TestObj::destroyed, this, &Test::echo);
        return QVariant::fromValue(obj);
    }
    void echo() { qDebug() << "it got destroyed"; }
};

QML:

function test() {
    var test = Test.getObject()
    console.log(test.objectName)
}

test() , , echo() , :

qml: that object
destructor called

gc() , , , , :

function test() {
    var test = Test.getObject()
    console.log(test.objectName)
    gc() // doesn't do anything
}

, :

function test2() {
    test()
    gc()
}

, , :

qml: that object
destructor called
it got destroyed

, , destroyed(), echo() , , , , . , Qt . Test main(), "", , QML, , , , echo() , , , . , , , .

+4

All Articles