gpt4 book ai didi

c++ - 如何管理返回给 QML 的动态分配的 QObject 的生命周期?

转载 作者:太空狗 更新时间:2023-10-29 20:58:35 27 4
gpt4 key购买 nike

我有这个代码:

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() 插槽永远不会被触发,但是来自析构函数确实出现在控制台中:

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(),但似乎并非如此。但这不是问题的范围,问题的重点是对象被管理,当它们不再被引用并触发垃圾收集时将被收集。

关于c++ - 如何管理返回给 QML 的动态分配的 QObject 的生命周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27315030/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com