Qt / C++: Is there a way to automatically register meta types?

1.5k Views Asked by At

In order to get all of the functionality of Qt's meta type system, I have to call qRegisterMetaType at runtime during the initialization of my application. Specifically, I need to register:

  • the pointer type for each of my QObject-derived classes, i.e. qRegisterMetaType<MyClass *>(), and
  • each type that I've declared as a meta type using Q_DECLARE_METATYPE.

Currently I do this with a function that just calls qRegisterMetaType for each one of these that I manually maintain and update as needed.

This, however, is rather inconvenient and error prone for me. I am often forgetful, and forgetting to register a metatype won't produce any compile errors, but it will cause runtime errors when my code tries to use the metatype system and fails because I forgot to register one of these. Sometimes the error can be difficult to track down.

So is there any way I can have all of my QObject-derived classes and declared metatypes get registered automatically?

Some things that might factor into a solution:

  • All of my QObject-derived classes I need registered are also derived from my own single base class, so I can use that to implement functionality that every other class will inherit.
  • I'm open to using arcane percompiler techinques if necessary!
1

There are 1 best solutions below

9
On BEST ANSWER

I can't figure out a way to automatically declare a meta type, i.e. without providing the Q_DECLARE_METATYPE macro in the class header, but one could provide a macro where registration is automatically performed (more or less along with meta type declaration). This example is meant to declare and register only the pointer type of a given class:

#include <QMetaType>

#define METAID(CLASS)                \
    Q_DECLARE_METATYPE(CLASS*)       \
    static struct CLASS##Metaid      \
    {                                \
      CLASS##Metaid()                \
      {                              \
        qRegisterMetaType<CLASS*>(); \
      }                              \
    } _CLASS##metaid;

The macro above can be used instead of Q_DECLARE_METATYPE:

class MyClass : public QObject
{
Q_OBJECT
};

METAID(MyClass)