我想在注册类中使用qmlRegiterType()
。我尝试使用此topic中的方法,但每当我尝试在调试模式下运行应用程序时,它会使应用程序崩溃并显示错误
在0x0读取访问冲突
在qqml.h
(235行)内的宏QML_GETTYPENAMES
上崩溃。
TestClass.h
:
class RegisterQmlTest : public QObject
{
Q_OBJECT
public:
explicit RegisterQmlTest(QObject *parent = 0);
};
TestClass.cpp
:
QML_REGISTER(RegisterQmlTest);
RegisterQmlTest::RegisterQmlTest(QObject *parent) : QObject(parent)
{ }
void RegisterQmlTest::foo()
{
qDebug() << "Foo test";
}
我尝试在Windows上的Qt 5.6.2上编译MSVC2013x64上的应用程序。
答案 0 :(得分:3)
你并不是唯一发生这种情况的人:https://github.com/benlau/quickflux/issues/7,我相信这可能是由于 static initialization order fiasco
一种解决方案可能是使用Q_COREAPP_STARTUP_FUNCTION
来确保对qmlRegisterType
的调用不会过早。
您可以在.cpp文件中使用此宏,如下所示:
static void registerMyQmlTypes() {
qmlRegisterType<MyType>("MyImortUri", 1, 0, "MyType");
}
Q_COREAPP_STARTUP_FUNCTION(registerMyQmlTypes)
答案 1 :(得分:0)
我有完全相同的问题。问题是,在宏调用staticMetaObject的调用时,与您的类关联的qmlRegisterType未初始化。正如this answer中所述(来自同一主题),您在没有宏的情况下会更灵活。我通过为每个自定义类引入一个静态类型来解决这个问题。
#include <functional>
#include <QtQml>
#include <QList>
namespace app {
namespace Qml {
namespace Register {
auto Init() -> void;
static auto GetList()->QList<std::function<void(void)>>&;
template <class T>
struct Type {
Type() {
auto initializer = []() {
qmlRegisterType<T>();
};
GetList().append(initializer);
}
};
}
}
}
#include "appQmlRegister.hpp"
namespace app {
namespace Qml {
namespace Register {
auto Init() -> void {
for (auto registerFunc : GetList()) {
registerFunc();
}
}
auto GetList()->QList<std::function<void(void)>>& {
static QList<std::function<void(void)>> List;
return List;
}
}
}
}
类型app::Qml::Register::Type
采用模板参数(自定义类的类型)并将调用包装在lambda中qmlRegisterType
。这就是基本概念。您现在可以完全控制何时通过app::Qml::Register::Init()
注册所有自定义类型,而不是立即通话。通过在运行时调用该函数但在启动QML引擎之前,您可以确保staticMetaObject已正确初始化,并且您可以安全地注册它们。
这需要在每个自定义类级别上进行一些输入。您必须在要在QML中注册的类的标头中声明一个静态成员:
#include "appQmlRegister.hpp"
namespace app {
class MyCustomClass : public QObject {
Q_OBJECT
private:
static Qml::Register::Type<MyCustomClass> Register;
// stuff...
}
}
然后在.cpp文件中定义它,如下所示:
#include "MyCustomClass.hpp"
namespace app {
Qml::Register::Type<MyCustomClass> MyCustomClass::Register;
}
这当然可以扩展为支持其他类型的注册,例如注册不可创建的类型,自定义版本/名称等。我在GitHub
上的QML展示/模板项目中实现了这一点。希望这有帮助!