[英]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.