Q_DECLARE_METATYPE and qRegisterMetaType?



  • Hello all,

    I am using Qt 5.4.2. I have an enum, ClientError, that I am trying to use in several ways:

    • A meta type for use with QVariants in a QAbstractListModel:
     errorVariant.canConvert<ErrorHandler::ClientError>()
    
    • A function parameter:
    ErrorModel::addError(ErrorHandler::ClientError)
    
    • A QML enum:
    errorModel.addError(ClientError.MajorError)
    

    ErrorHandler.h contains the following:

    class ErrorHandler : public QObject
    {
        Q_OBJECT
        Q_ENUMS(ClientError)
    public:
        enum ClientError
        {
            MajorError,
    ...
    ...
    };
    
    Q_DECLARE_METATYPE(ErrorHandler::ClientError)
    
    #endif // ERRORHANDLER_H
    

    Main.cpp contains the following:

    #include <client/ErrorHandler.h>
    
    int main(int argc, char **argv)
    {
    ...
    ...
        qRegisterMetaType<ErrorHandler::ClientError>("ErrorHandler::ClientError");
        qmlRegisterUncreatableType<ErrorHandler>("Client", 1, 0, "ClientError","Display Client Errors");
    

    When I build, I get the following:

    main.obj:-1: error: LNK2019: unresolved external symbol "public: static struct QMetaObject const ErrorHandler::staticMetaObject" (?staticMetaObject@ErrorHandler@@2UQMetaObject@@B) referenced in function "int __cdecl qRegisterNormalizedMetaType<class ErrorHandler *>(class QByteArray const &,class ErrorHandler * *,enum QtPrivate::MetaTypeDefinedHelper<class ErrorHandler *,1>::DefinedType)" (??$qRegisterNormalizedMetaType@PEAVErrorHandler@@@@YAHAEBVQByteArray@@PEAPEAVErrorHandler@@W4DefinedType@?$MetaTypeDefinedHelper@PEAVErrorHandler@@$00@QtPrivate@@@Z)
    

    Am I doing anything wrong? Is it possible to double-use an enum in this way?

    Thanks.



  • Q_ENUMS is deprecated, use Q_ENUM that already includes the Q_DECLARE_METATYPE so no need to explicitly add it. Also you don't need to register QObject derived types



  • I'm currently using Qt 5.4.2; it seems like that's a newer feature.


  • Qt Champions 2016

    Is this a library? I mean where you define the ErrorHandler class. If so you need to export that class from it.

    PS. Also use qRegisterMetaType without a string argument:

    qRegisterMetaType<ErrorHandler::ClientError>();
    


  • By export you mean "CONFIG += client" in clientApp.pro, correct?

    I tried without a string argument, same result.


  • Qt Champions 2016

    Not at all, unless your library is a module QT += is not going to work and CONFIG += is for qmake features/configurations so it has no place here. I mean like described here.



  • It is a library and it's exported correctly. I am able to access a different enum from a different class in the same library from QML; the only difference is me using Q_DECLARE_METATYPE with ClientError.


  • Qt Champions 2016

    @EStudley said in Q_DECLARE_METATYPE and qRegisterMetaType?:
    Firstly, you shouldn't need to use Q_DECLARE_METATYPE (or qRegisterMetaType) with the enum at all, this is handled by the moc. Here you can see that the macro expands to nothing.
    Secondly, your linker (MSVC) complains that it can't find the metaObject for your ErrorHandler enum, which is normal as it is not exported from the binary by Q_DECLARE_METATYPE.

    In conclusion:
    Don't use Q_DECLARE_METATYPE and qRegisterMetaType for your QObject enum. Use it if you want to use it as a global enumerator and then you need to call the meta-type runtime registration from the library, not from the application.



  • Thanks! That seemed to solve my issues.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.