![](/img/trans.png)
[英]Qt Quick2 Creating qmlRegisterSingletonType for Singleton Class Type
[英]How to implement a singleton provider for qmlRegisterSingletonType?
我想在 QML 中使用 C++ 類作為單例實例,並認為我必須使用 qmlRegisterSingletonType 注冊它們。 此函數需要一個函數,該函數提供已注冊 C++ 類的實例。 我在 Windows 上使用包含 MinGW 4.8 的最新 Qt 5.3.1。
該文檔顯示了以下提供程序函數的示例:
static QJSValue example_qjsvalue_singletontype_provider(QQmlEngine *engine,
QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
static int seedValue = 5;
QJSValue example = scriptEngine->newObject();
example.setProperty("someProperty", seedValue++);
return example;
}
我嘗試使用它,但是當我在頭文件的類范圍之外定義這樣一個函數時,我收到編譯器警告,發生在另一個包含相同頭文件的 cpp 文件中:
warning: 'QObject* example_qjsvalue_singletontype_provider(QQmlEngine*,
QJSEngine*)' defined but not used [-Wunused-function]
此外,編寫一個從不同的 cpp 文件調用時返回一個新實例的單例提供程序感覺是錯誤的。 所以我嘗試了一個自己的實現,我使用靜態類成員來返回實例:
// mysingleton.h
class MySingleton: public QObject
{
Q_OBJECT
Q_DISABLE_COPY(MySingleton)
public:
static QObject *qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine) {
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
if(!m_instance)
{
m_instance = new MySingleton();
}
return m_instance;
}
MySingleton(QObject* parent = 0)
:QObject(parent)
{}
private:
static QObject* m_instance;
};
我嘗試使用...
qmlRegisterSingletonType<MySingleton>(uri, 1, 0, "MySingleton",
MySingleton::qmlInstance);
此解決方案也不起作用,我收到鏈接器錯誤:
release/main.o:main.cpp:
(.text$_ZN11MySingleton11qmlInstanceEP10QQmlEngineP9QJSEngine[__ZN11MySingleton11
qmlInstanceEP10QQmlEngineP9QJSEngine]+0x42): undefined reference to
`MySingleton::m_instance'
提供所需的單例實例 1) 具有類范圍之外的函數和 2) 具有類成員函數的正確解決方案是什么?
為什么該示例建議在每次調用提供程序函數時創建一個新實例?
編寫一個單獨的提供程序,從不同的cpp文件調用時返回一個新實例,這是錯誤的。 所以我嘗試了一個自己的實現,我使用靜態類成員來返回實例
從文檔引用到qmlRegisterSingletonType
函數:
注意:從單一類型提供程序返回的QObject單例類型實例由QML引擎擁有。 出於這個原因,單類型提供的功能不應該被實現為一個單獨的工廠。
這意味着當單例類型提供程序返回一個新實例時,這種行為是通過意圖完成的,盡管事實上它正如你所指出的那樣,乍一看看起來很奇怪。 所以,你的類實現應該如下所示:
class MySingleton: public QObject
{
Q_OBJECT
Q_DISABLE_COPY(MySingleton)
MySingleton() {}
public:
static QObject *qmlInstance(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine);
Q_UNUSED(scriptEngine);
return new MySingleton;
}
};
此外,您應該為MySingleton::qmlInstance
使用&符號,因為它是一個成員方法。 有關詳細信息,請參閱此 然后注冊看起來應該如此:
qmlRegisterSingletonType<MySingleton>(uri, 1, 0, "MySingleton", &MySingleton::qmlInstance);
問題是(您的第二個示例)您必須初始化m_instance靜態成員變量。 您可以在mysingleton.cpp文件中執行此操作,例如:
QObject * MySingleton::m_instance = 0;
在 Qt 5.6 中, qmlRegisterSingletonType
文檔中的qmlRegisterSingletonType
已更新:
注意:從單例類型提供程序返回的 QObject 單例類型實例歸 QML 引擎所有,除非該對象明確設置了 QQmlEngine::CppOwnership 標志。
因此,您可以完全控制單例實例的創建方式。 這是一個使用Q_GLOBAL_STATIC
的示例:
Q_GLOBAL_STATIC(MySingleton, singletonInstance)
MySingleton::MySingleton(QObject *parent) :
QObject(parent)
{
QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership);
}
Clipboard *MySingleton::instance()
{
return singletonInstance();
}
QObject *MySingleton::qmlInstance(QQmlEngine *, QJSEngine *)
{
return MySingleton::instance();
}
如果你想從c ++調用這個單例類,請更改該行
return new MySingleton;
至:
return new &MySingleton;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.