[Interest] how can I call qRegisterMetaType?

Hamish Moffatt hamish at risingsoftware.com
Mon May 16 04:33:58 CEST 2016


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!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!@BaseThreadInitThunk at 12()    Unknown
      ntdll.dll!__RtlUserThreadStart()    Unknown
      ntdll.dll!__RtlUserThreadStart at 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



More information about the Interest mailing list