【问题标题】:Resolving property and function "overrides" in QML在 QML 中解析属性和函数“覆盖”
【发布时间】:2015-11-23 15:49:06
【问题描述】:

看起来虽然 QML 支持“覆盖”属性和函数,但这种支持有点笨拙。这是一个示例 sn-p:

// 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])
    }
}

覆盖的行为是一致的——无论一个成员被覆盖多少次,你总是得到正确的,即使你做了这样的事情:

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

虽然该属性是用 T1 类型声明的,但它引用了一个 T2 对象,因此输出显示为“blah blah”。

它也适用于“每个实例”:

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

迭代 T1 的输出与预期一致:

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

但是,T2 的输出有点奇怪:

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” - 因此同样适用于“覆盖”函数。

我预计迭代“派生”对象会显示属性和函数两次,但其中之一将来自基本类型。让它们实际上是重复的,两者都指代同一个成员似乎毫无意义且不合逻辑。在实例级别覆盖放置另一个成员,并且再次,所有三个都引用最新的覆盖。因此,从技术上讲,甚至无法手动选择覆盖。

所以我的问题是是否可以指定覆盖:

// 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's p
f() { return f() + "blah" } //  stack overflow, f does not refer to T1's f

【问题讨论】:

    标签: javascript function properties overriding qml


    【解决方案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
    }
    

    简而言之,为覆盖的“继承”的每一级显式命名函数,并使用非修饰函数覆盖进行多态访问,因此现在“基”类型的实现可以被派生重用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-22
      • 2014-03-08
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      相关资源
      最近更新 更多