How to check if it's a valid QObject pointer, created by QMetaType::create()

491 Views Asked by At

I need to convert QVariant to other user custom classes.

All classes have to be derived from QObject.

I can check at compilation time the destination type because it's a template but the source is a QVariant so, it cannot be checked.

My method:

template<class T, typename = std::enable_if_t<std::is_base_of<QObject, T>::value> > static bool canConvert(const QVariant& var)

calls this:

QObject* from = reinterpret_cast<QObject*>(QMetaType::create(var.userType()));

from is never null but, if userType is not of a QObject base class, from is not a valid QObject pointer and the call crashes when calling:

from->metaObject();

I cannot do dynamic_cast of a void* from QMetaType::create()

I tried qobject_cast of from but it does not fail if it's not valid

How do I know if QObject* from is a valid pointer to a QObject derived class?

1

There are 1 best solutions below

0
On

I've found a solution.

If the type is, for example MyType, it's pointer type has to be registered.

qRegisterMetaType<MyType*>();

So, here a rudimental method to check if it's derived from QObject:

    static bool isClassDerivedFromQObject(const QVariant& var)
    {
        QString className(QMetaType::typeName(var.userType()));
        className.append("*"); // create a pointer of the name
        const auto id = QMetaType::type(className.toLatin1().data());
        const auto metaObject = QMetaType::metaObjectForType(id);
        return metaObject != nullptr;
    }

This can be called before QMetaType::create(var.userType())