Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print a list of custom properties of a QML object?

Tags:

qt

qt5

qml

Having created a QML QtObject:

QtObject {
    property int p: 42
    property int q: 44
}

After storing it in a local variable QObject *obj, how to print all custom property names and possibly values (i.e. only p and q for the example above)? I'd like this to work for any class (not just QtObject) and not print properties that were already declared with Q_PROPERTY.

Clarification: by "custom" I do not mean properties added through QObject::setProperty that were not declared using Q_PROPERTY. I mean properties declared in QML through property <type> <name>: <value> notation that were not declared using Q_PROPERTY in QObject subclass for that QML object. Quick test shows that those properties do not come up in QObject::dynamicPropertyNames.

like image 318
Xilexio Avatar asked Dec 14 '22 19:12

Xilexio


1 Answers

C++ and QML approach

To print only dynamic property names, you can use the very aptly named dynamicPropertyNames() function of QObject from within an invokable C++ function:

#include <QGuiApplication>
#include <QtQml>

class Object : public QObject
{
    Q_OBJECT
    Q_PROPERTY(int staticProperty READ staticProperty)
public:
    Object() {
        setProperty("dynamicProperty", 1);
    }

    int staticProperty() const {
        return 0;
    }

    Q_INVOKABLE void printDynamicPropertyNames() const {
        qDebug() << dynamicPropertyNames();
    }
};

int main(int argc, char** argv)
{
    QGuiApplication app(argc, argv);

    Object object;

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("object", &object);
    engine.load("main.qml");

    return app.exec();
}

#include "main.moc"

main.qml:

import QtQuick 2.3
import QtQuick.Controls 1.2

ApplicationWindow {
    width: 400
    height: 400
    visible: true

    Component.objectName: object.printDynamicPropertyNames()
}

Output:

("dynamicProperty")

QML-only approach

If you want to print all properties of an object, dynamic or not, purely with QML, use JavaScript's for...in syntax:

The for..in statement iterates over the enumerable properties of an object, in arbitrary order. For each distinct property, statements can be executed.

import QtQuick 2.2

Rectangle {
    id: rect
    width: 360
    height: 360

    Component.onCompleted: {
        for (var prop in rect) {
            print(prop += " (" + typeof(rect[prop]) + ") = " + rect[prop]);
        }
    }
}

Output:

qml: objectName (string) = 
qml: parent (object) = null
qml: data (object) = [object Object]
qml: resources (object) = [object Object]
qml: children (object) = [object Object]
qml: x (number) = 0
qml: y (number) = 0
qml: z (number) = 0
qml: width (number) = 360
qml: height (number) = 360
qml: opacity (number) = 1
qml: enabled (boolean) = true
...
like image 88
Mitch Avatar answered Dec 24 '22 16:12

Mitch