Property and function resolution overrides in QML

It seems that although QML supports "overriding" properties and functions, support is somewhat awkward. Here is an example snippet:

// T1.qml
QtObject {
    property int p: 1
    function f() { return 1 }
}

// T2.qml
T1 {
    property string p: "blah"
    function f() { return "blah" }
}


// usage
T1 {
    Component.onCompleted: {
        var obj = this
        for (var k in obj) console.log(k + " " + typeof obj[k] + " " + obj[k])
    }
}

T2 {
    Component.onCompleted: {
        var obj = this
        for (var k in obj) console.log(k + " " + typeof obj[k] + " " + obj[k])
    }
}

The behavior of the overrides is consistent - no matter how many times a member has been redefined, you always get the correct one, even if you do something like this:

QtObject {
    property T1 p : T2 {}
    Component.onCompleted: console.log(p.p + " " + p.f())
}

Although a property is declared with type T1, it refers to a T2 object, and therefore the output says "blah blah".

It also works on a per-instance basis:

T2 {
    function f() { return 1.5 }
    Component.onCompleted: {
       console.log(f())
    }
}

The output from iteration T1 will be as expected:

qml: objectName string 
qml: p number 1
qml: objectNameChanged function function() { [code] }
qml: pChanged function function() { [code] }
qml: f function function() { [code] }

However, the output for T2 is a bit odd:

qml: objectName string 
qml: p string blah
qml: p string blah
qml: objectNameChanged function function() { [code] }
qml: pChanged function function() { [code] }
qml: f function function() { [code] }
qml: pChanged function function() { [code] }
qml: f function function() { [code] }

"" , , , "", - "", p .

var obj = this
for (var k in obj) if ((k === "f") && (typeof obj[k] === "function")) console.log(obj[k]())

f "blah" - , "overrides".

, "" , . , . , . .

, , :

// in T2.qml - pseudocode
property string p: T1::p + "blah" //  value is "1 blah"
f() { return T1:: f() + "blah" } //  returning "1 blah"

:

// in T2.qml
property string p: p + "blah" //  binding loop, p does not refer to T1 p
f() { return f() + "blah" } //  stack overflow, f does not refer to T1 f
+4
1

:

// T1.qml
QtObject {
    function f() { return f_t1() }
    function f_t1() { return 1 }
}

// T2.qml
T1 {
    function f() { return f_t2() }
    function f_t2() { return f_t1() + " blah " }
}

// usage
T2 {
    function f() { return f_t2() + 1.5}
    Component.onCompleted: console.log(f()) // outputs 1 blah 1.5
}

, "", , , .

+1

Source: https://habr.com/ru/post/1617093/


All Articles