是否可以卸载通过QQmlApplicationEngine::load() 加载的QML对象?
我有一个C++类,它暴露了一个属性,并且有一个使用它的QML接口。下面是一个可工作的示例(test.cpp):
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtQuick/QQuickItem>
class Exposed : public QQuickItem {
Q_OBJECT
public:
Q_PROPERTY(int property READ getProperty NOTIFY never)
~Exposed() { qInfo() << "I'm done for"; }
int getProperty() {
qInfo() << "What's the meaning of all this?..";
return 42;
}
signals:
void never();
};
int main(int argc, char* argv[]) {
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Exposed e;
engine.rootContext()->setContextProperty("exposed", &e);
engine.load("test.qml");
return app.exec();
}
#include "test.moc"
以及QML(test.qml):
import QtQuick
import QtQuick.Controls
ApplicationWindow {
visible: true
Text { text: exposed.property }
}
程序输出如下:
What's the meaning of all this?..
I'm done for
file:///home/user/work/test-qt/test.qml:6: TypeError: Cannot read property 'property' of null
错误信息之所以出现,是因为 e 在 engine 之前被删除。通过交换对象定义的顺序,我可以避免这个问题:
...
Exposed e;
QQmlApplicationEngine engine;
...
现在引擎在暴露对象之前被销毁,一切正常。
但如果我无法控制对象的创建/销毁顺序(代码不是我写的)呢?有没有办法手动卸载用 QQmlApplicationEngine::load() 加载的QML接口?大致像这样:
QQmlApplicationEngine engine;
Exposed e;
engine.rootContext()->setContextProperty("exposed", &e);
engine.load("test.qml");
app.exec();
engine.unload_the_object_loaded_two_lines_above();
// e will still be destroyed before engine but that's fine because nobody needs it anymore
请不要对这个问题过于字面地理解,如果你认为整件事应该以不同的方式完成,或者对该主题有其他看法,欢迎提出。
解决方案
没有直接的卸载方式,但你可以通过销毁根对象来达到同样的效果。
for (QObject* obj : engine.rootObjects())
delete obj;
或者你可以将Loader作为根元素,并将其source设为空字符串,这样其子项就会被“卸载”。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。