[英]qmlRegisterSingletonType and multiple top-level windows
I have a QGuiAppplication
derived class (called Sy_application
) that I've wrapped with another (called Sy_application_qml
, with extra some QML specific features) and then registered that as a singleton with the QML engine. 我有一个
QGuiAppplication
派生类(称为Sy_application
),该类已经包装了另一个类(称为Sy_application_qml
,具有其他一些QML特定功能),然后将其注册为QML引擎的单例。
This all works fine from the first opened top-level window, but the second (and presumably any more) only gets null
from the singleton. 所有这些都可以从第一个打开的顶级窗口正常运行,但是第二个(可能还有更多)仅从单例中获取
null
。 Adding some debug: 添加一些调试:
// The static factory method used in the qmlRegisterSingletonType call.
QObject* Sy_application_qml::factory( QQmlEngine* engine,
QJSEngine* scriptEngine )
{
Q_UNUSED( engine )
Q_UNUSED( scriptEngine )
qDebug() << "Creating";
return new Sy_application_qml();
}
// SY_APP is the qApp macro casted to my Sy_application type.
QObject* Sy_application_qml::get()
{
qDebug() << "Getting:" << SY_APP;
return SY_APP;
}
// This is an example of it's use within QML
onPositiveClicked: {
console.log( Sy_application_qml );
Sy_application_qml.get().newProject( sampleRate.value, frameRate.value );
close();
}
And the debug output: 和调试输出:
// Opening first window.
Creating
// Creating second
qml: Sy_application_qml(0x1895b30)
Getting: Sy_application(0x7fff80f051c0)
// Attempting to create third
qml: Sy_application_qml(0x1895b30)
Getting: Sy_application(0x7fff80f051c0)
qrc:/qml/gui/dialogs/Sy_newProjectDialog.qml:62: TypeError: Cannot call method 'newProject' of null
As you can see the singleton is still present and the C++ Sy_application
instance is being returned correctly, but is appearing as null
on the QML side. 如您所见,单例仍然存在,并且C ++
Sy_application
实例已正确返回,但在QML端显示为null
。 Any reason why it works for one window and not another? 它对一个窗口而不对另一个窗口起作用的任何原因是什么?
So I finally worked it out, and it had nothing to do with QML singletons or having multiple top-level windows - but it had everything to do with passing QObject
pointers to the QML engine from Q_INVOKABLE
methods (the Sy_application_qml::get()
method in my case). 所以我终于解决了这个问题,它与QML单例无关,也没有多个顶层窗口-但这与从
Q_INVOKABLE
方法( Sy_application_qml::get()
方法Sy_application_qml::get()
传递QObject
指针到QML引擎有关。就我而言)。
From the docs: 从文档:
Objects not-created by QML have CppOwnership by default.
默认情况下,不是由QML创建的对象具有CppOwnership。 The exception to this is objects returned from C++ method calls;
从C ++方法调用返回的对象是一个例外。 in these cases, the ownership of the returned objects will be set to JavaScriptOwnerShip.
在这些情况下,返回对象的所有权将设置为JavaScriptOwnerShip。 Note this applies only to explicit invocations of Q_INVOKABLE methods or slots, and not to property getter invocations.
请注意,这仅适用于Q_INVOKABLE方法或插槽的显式调用,不适用于属性getter调用。
So the QML engine had deleted my Sy_application
pointer. 因此,QML引擎删除了我的
Sy_application
指针。 The solution was nice and simple: 解决方案非常简单:
QObject* Sy_application_qml::factory( QQmlEngine* engine,
QJSEngine* scriptEngine )
{
Q_UNUSED( engine )
Q_UNUSED( scriptEngine )
QQmlEngine::setObjectOwnership( SY_APP, QQmlEngine::CppOwnership );
return new Sy_application_qml();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.