binzo
binzo

Reputation: 115

Qml property hooks

Suppose there is a Qml type called Test with foo property, it is implemented as follows: Test.qml

// Not necessarily QtObject, but derived from QObject
QtObject {
    // Not necessarily var/property, but must behave like property (i.e. be accessible using "<instance>.foo")
    property var foo
}

And used in the following way: main.qml

import "."

Test {
    id: _test
}

function baz() {
    var x = _test.foo;
    _test.foo = x;
}

What I want is to be notified every time foo property is accessed by getter or setter. For setter perhaps I can use fooChanged signal, but there is no such solution for getter. Also I could implement Test type as a C++ class with Q_PROPERTY macro and emit corresponding signals form property getter/setter, but I would really like to leave most of the code on Qml side.

Is there any other way to hook Qml properties access?

Upvotes: 4

Views: 2230

Answers (1)

binzo
binzo

Reputation: 115

Ok, after some hours of googling, reading Qml and JS documentation I think I have finally found a solution. It involves some hacks since JS is not fully supported in Qml, but this solution still works. The main idea is to use JS defineProperty method in order to add properties to existing objects dynamically. Now my Test.qml file looks like this:

QtObject {
    // NOTE: .defineProperty does not correctly work for Qml objects, so JS object is used instead
    property var object: { return {}; }

    Component.onCompleted: {
        Object.defineProperty(
            object,
            "foo",
            {
                get: function () {
                    // getter handling here
                },
                set: function (value) {
                    // setter handling here
                }
            }
        );
    }
}

And in main.qml _test instance is declared as follows:

property alias _test: _testDeclaration.object

Test {
    id: _testDeclaration
}

Hope this answer will help other people.

Upvotes: 6

Related Questions