Hamish Moffatt
2016-05-16 02:33:58 UTC
I've got an enum in a class which I need to register with
qRegisterMetaType() (in order to use it in object properties). I also
need to register some converters with QMetaType::registerConverter().
class MyQuestion : public QObject
{
Q_OBJECT
public:
enum QuestionType { TYPE_A, TYPE_B, TYPE_C, TYPE_D };
Q_ENUM(QuestionType)
};
Is there a way to keep the call to qRegisterMetaType to the class so
that the code using my class doesn't need to worry about it? For example
I tried using a class member and method, as in
bool MyQuestion::registered = registerTypes();
bool MyQuestion::registerTypes()
{
qRegisterMetaType<MyQuestion::QuestionType>("QuestionType");
}
However this blows up in the qRegisterMetaType call which suggests that
the initialisation happened too early. It looks like it happened before
the Q_ENUM worked its magic. Here's the stack trace (MSVC 2013):
Qt5Cored.dll!objectClassName(const QMetaObject * m=0x002fa404)
Line 301 C++
Qt5Cored.dll!QMetaObject::className() Line 311 C++
json.exe!QMetaTypeId2<enum
MyQuestion::QuestionType>::qt_metatype_id() Line 1584 C++
json.exe!QtPrivate::QMetaTypeIdHelper<enum
MyQuestion::QuestionType,1>::qt_metatype_id() Line 1597 C++
json.exe!qRegisterNormalizedMetaType<enum
MyQuestion::QuestionType>(const QByteArray & normalizedTypeName={...},
MyQuestion::QuestionType * dummy=0x00000000,
QtPrivate::MetaTypeDefinedHelper<enum
MyQuestion::QuestionType,1>::DefinedType defined=Defined) Line 1666 C++
json.exe!qRegisterMetaType<enum MyQuestion::QuestionType>(const
char * typeName=0x002f6370, MyQuestion::QuestionType * dummy=0x00000000,
QtPrivate::MetaTypeDefinedHelper<enum
MyQuestion::QuestionType,1>::DefinedType defined=Defined) Line 1705 C++
json.exe!MyQuestion::registerTypes() Line 22 C++
json.exe!`dynamic initializer for 'MyQuestion::registered''() Line
14 C++
msvcr120d.dll!_initterm(void (void) * * pfbegin=0x002f5240, void
(void) * * pfend=0x002f5370) Line 955 C
json.exe!__tmainCRTStartup() Line 550 C
json.exe!WinMainCRTStartup() Line 466 C
kernel32.dll!@***@12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!***@8() Unknown
Should I just do it from the constructor? Would I need to worry about
thread safety then, if my class was created in a bunch of threads at the
same time while this is going on?
thanks,
Hamish
qRegisterMetaType() (in order to use it in object properties). I also
need to register some converters with QMetaType::registerConverter().
class MyQuestion : public QObject
{
Q_OBJECT
public:
enum QuestionType { TYPE_A, TYPE_B, TYPE_C, TYPE_D };
Q_ENUM(QuestionType)
};
Is there a way to keep the call to qRegisterMetaType to the class so
that the code using my class doesn't need to worry about it? For example
I tried using a class member and method, as in
bool MyQuestion::registered = registerTypes();
bool MyQuestion::registerTypes()
{
qRegisterMetaType<MyQuestion::QuestionType>("QuestionType");
}
However this blows up in the qRegisterMetaType call which suggests that
the initialisation happened too early. It looks like it happened before
the Q_ENUM worked its magic. Here's the stack trace (MSVC 2013):
Qt5Cored.dll!objectClassName(const QMetaObject * m=0x002fa404)
Line 301 C++
Qt5Cored.dll!QMetaObject::className() Line 311 C++
json.exe!QMetaTypeIdQObject<enum
MyQuestion::QuestionType,16>::qt_metatype_id() Line 1806 C++json.exe!QMetaTypeId2<enum
MyQuestion::QuestionType>::qt_metatype_id() Line 1584 C++
json.exe!QtPrivate::QMetaTypeIdHelper<enum
MyQuestion::QuestionType,1>::qt_metatype_id() Line 1597 C++
json.exe!qRegisterNormalizedMetaType<enum
MyQuestion::QuestionType>(const QByteArray & normalizedTypeName={...},
MyQuestion::QuestionType * dummy=0x00000000,
QtPrivate::MetaTypeDefinedHelper<enum
MyQuestion::QuestionType,1>::DefinedType defined=Defined) Line 1666 C++
json.exe!qRegisterMetaType<enum MyQuestion::QuestionType>(const
char * typeName=0x002f6370, MyQuestion::QuestionType * dummy=0x00000000,
QtPrivate::MetaTypeDefinedHelper<enum
MyQuestion::QuestionType,1>::DefinedType defined=Defined) Line 1705 C++
json.exe!MyQuestion::registerTypes() Line 22 C++
json.exe!`dynamic initializer for 'MyQuestion::registered''() Line
14 C++
msvcr120d.dll!_initterm(void (void) * * pfbegin=0x002f5240, void
(void) * * pfend=0x002f5370) Line 955 C
json.exe!__tmainCRTStartup() Line 550 C
json.exe!WinMainCRTStartup() Line 466 C
kernel32.dll!@***@12() Unknown
ntdll.dll!__RtlUserThreadStart() Unknown
ntdll.dll!***@8() Unknown
Should I just do it from the constructor? Would I need to worry about
thread safety then, if my class was created in a bunch of threads at the
same time while this is going on?
thanks,
Hamish