我正在尝试使用一个非静态方法作为Qt 5中qmlRegisterSingletonType的回调方法。我的代码如下:
PersistentLong couponCounter("couponCounter", handler.getSubjectRunner(), handler.getDbManager());
qmlRegisterSingletonType<PersistentLong>("MyNamespace", 1, 0, "CouponCounter", couponCounter.factory);
但我得到以下编译器错误:
/.../src/Main.cxx: In function ‘int main(int, char**)’:
/.../src/Main.cxx:22:102: error: no matching function for call to ‘qmlRegisterSingletonType(const char [9], int, int, const char [14], <unresolved overloaded function type>)’
qmlRegisterSingletonType<PersistentLong>("MyNamespace", 1, 0, "CouponCounter", couponCounter.factory);
^
/.../src/Main.cxx:22:102: note: candidate is:
In file included from /usr/local/Qt-5.3.2/include/QtQml/QtQml:9:0,
from /.../src/Main.cxx:6:
/usr/local/Qt-5.3.2/include/QtQml/qqml.h:476:12: note: template<class T> int qmlRegisterSingletonType(const char*, int, int, const char*, QObject* (*)(QQmlEngine*, QJSEngine*))
inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
^
/usr/local/Qt-5.3.2/include/QtQml/qqml.h:476:12: note: template argument deduction/substitution failed:
/.../src/Main.cxx:22:102: note: cannot convert ‘couponCounter.PersistentLong::factory’ (type ‘<unresolved overloaded function type>’) to type ‘QObject* (*)(QQmlEngine*, QJSEngine*)’
qmlRegisterSingletonType<PersistentLong>("MyNamespace", 1, 0, "CouponCounter", couponCounter.factory);
PersistentLong
的factory
方法如下:
QObject * factory(QQmlEngine *engine, QJSEngine *scriptEngine) {
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return this;
}
问题
关于为什么我不能用这个方法作为qmlRegisterSingletonType
的论据,有什么想法吗?
有没有其他方法可以在QML中将非静态实例注册为singleton?
编辑1
couponCounter在main()
中以以下方式构建:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtSubjectHandler handler("burgundy_frontend");
PersistentLong couponCounter("couponCounter", handler.getSubjectRunner(), handler.getDbManager());
qmlRegisterSingletonType<PersistentLong>("MyNamespace", 1, 0, "CouponCounter", couponCounter.factory);
}
如果我使用函数指针,我如何在这个函数中引用couponCounter
?
关于为什么我不能用这个方法作为
qmlRegisterSingletonType
的论据,有什么想法吗?
考虑到factory
方法的使用,我可以猜测它是类的一个成员函数,您正在使用它作为回调。但是,注册功能具有以下签名:
int qmlRegisterSingletonType(const char * uri, int versionMajor, int versionMinor, const char * typeName, QObject *(* ) ( QQmlEngine *, QJSEngine * ) callback)
正如您所看到的,最后一个参数是函数指针,但您(试图)将指针传递给成员函数这是完全不同的。请注意,在这种情况下,friend
函数和static
函数都不能被利用,因为它们都无法访问this
指针。
有没有其他方法可以在QML中将非静态实例注册为singleton?
编写和编译这样的全局函数是完全可行的(static
,你在哪里?):
QObject *provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return new MyNiceObject();
}
并像这样注册:
qmlRegisterSingletonType<AppInfo>("AppInfo", 1, 0, "AppInfo", provider);
除了我删除的static
之外,Digia示例使用了这种方法。不幸的是,文档非常模糊,并且没有提供使用static
修饰符的具体原因,所以我唯一可以考虑的原因是可见性目的。任何更知情/更熟练的人都可以纠正我的错误,并告诉我们是否有更具体的/思考的原因(例如任何特定的内存管理原因)。
最后,重点是为QML引擎提供一个创建我们类型的实例的函数,而这样的结果不能用成员函数来实现。
顺便说一句,如果您更喜欢返回一个singleton实例,您可以利用singleton模式(再次使用static
修饰符)并重写如下函数:
QObject *provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
MyNiceObject * p = MyNiceObject::instance(); // uhmmmm static...
QQmlEngine::setObjectOwnership(p, QQmlEngine::CppOwnership);
return p;
}
请注意,所创建对象的所有权默认情况下赋予QML引擎。为了避免这个问题,可以使用CCD_ 15调用。