簡體   English   中英

如何管理動態分配QObject的生命周期返回QML?

[英]How to manage lifetime of dynamically allocated QObject returned to QML?

我有這個代碼:

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);
}

但是從不調用Factory::echo() ,這意味着每次調用函數時對象都會泄露。

這就是我在QML方面所擁有的:

onClicked: {          
    var code =
        'import QtQuick 2.3
        Rectangle {
            width: 50
            height: 50
            color: "blue"
        }
        '

    stack.push(Factory.componentFromCode(code))
    gc()
}

我明確設置了對象所有權,並顯式調用gc()來強制進行垃圾收集,但destroyed()信號永遠不會被釋放,因此對象永遠不會被刪除。 根據我的閱讀,這應該在QML中自動發生。

請注意,它適用於:

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

但它只是不方便,我想讓對象在超出范圍時自動銷毀,或者只要它被QML代碼引用就會保持活着,並在不再需要時被銷毀,在許多情況下手動執行可能很難/荒謬。

編輯:堆棧示例碰巧是我的實際代碼,但我想這不是一個好例子,看看堆棧如何承擔組件的所有權。 即使在如此簡單的情況下,我也無法獲得任何終身管理:

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

我不認為物體在泄漏。 試試這個:

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()槽,但是析構函數中的debug語句確實顯示在控制台中:

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的設計還是bug的產物。 Test對象在main()的堆棧上實例化,所以當QML管理的對象被破壞時,它應該仍然是“活着的”,應該是它使用的事件循環,所以我希望之前看到echo()應用程序退出,但似乎並非如此。 但這不是問題的范圍,問題的關鍵是對象被管理,並且當它們不再被引用並且觸發垃圾收集時將被收集。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM