0

In QML, how can I query for the type of a property of an item via reflection?

I.e. I have an Item C with a property x of type real and a property y of type string; at some other callsite I have an instance of C and want to query the type of its property x. With plain Qt, I can use QMetaObject, but how to do the same with QML?

pmf
  • 7,619
  • 4
  • 47
  • 77
  • Have you tried using `typeof`. This should return the corresponding javascript type, i.e. string, number, object, etc. but won't return a c++ type. Using it on any QObject class for example will always return "object" – Felix Oct 19 '18 at 08:33
  • 1
    typeof will also return 'string' or 'number' for properties of type 'var' that happen to have a current value of these types – pmf Oct 19 '18 at 08:40

1 Answers1

3

As in JavaScript, you can use typeof:

QtObject {
    id: c
    property real x
    property string y
    property int z
    Component.onCompleted: print(typeof c.x, typeof c.y, typeof c.z)
}

This will print qml: number string number.

Note that there is no difference here between x and z even though they are not of the same type, that's because JavaScript knows of only 1 number type, every number is 64-bit floating point*.

If you want to know how types are actually stored by the Qt engine, you would have to do as you mentionned in your question, use QMetaObject. For that you can expose a c++ type as a qml singleton, and expose an invokable method in it returning the typename of an object's property :

#ifndef METAOBJECTHELPER_H
#define METAOBJECTHELPER_H

#include <QMetaObject>
#include <QObject>
#include <QQmlProperty>

class MetaObjectHelper : public QObject {
    Q_OBJECT
public:
    using QObject::QObject;
    Q_INVOKABLE QString typeName(QObject* object, const QString& property) const
    {
        QQmlProperty qmlProperty(object, property);
        QMetaProperty metaProperty = qmlProperty.property();
        return metaProperty.typeName();
    }
};

#endif // METAOBJECTHELPER_H

Doing this in QML :

print(MetaObjectHelper.typeName(c, "x"), MetaObjectHelper.typeName(c, "y"), MetaObjectHelper.typeName(c, "z"));

Will then print qml: double QString int

* : more nuanced details here

GrecKo
  • 6,615
  • 19
  • 23