QML组件范围之谜(QML component scope puzzle)

2019-07-30 06:54发布

把这个代码:

import QtQuick 1.1

Rectangle {
    width:  100
    height: 100

    property color fromColor: "red"
    property color toColor:   "blue"

    gradient: Gradient {
        property color fromColor: "yellow"
        property color toColor:   "green"

        GradientStop { position: 0; color: fromColor }
        GradientStop { position: 1; color: toColor }
    }
}

为什么不完全相同的Gradient挑了fromColortoColor从封闭元素属性?

这哪里是记录(至少在源代码注释,更好的官方文档中)?

注:此“QML混淆的例子就是从吉里什莱玛克里斯南的谈话Qt Quick的最佳实践和设计模式 (后退到第25分钟),在那里他也说,事情是非常复杂的,必须与组件的范围和像,但已经没有时间解释为什么。

[UPDATE]

所以,作为MartinJ下面讲述,在元件特性的顶级组件(不仅是元素的孩子)层次都有其属性,所有的属性然而嵌套深可见,与特性的属性的优先级之中,和所有属性“中间”的项目根本看不见。

这里有一个小例子:

import QtQuick 1.1

Item {
    Item {
        property string s: "parent-str"
        Item { Component.onCompleted: console.log(s) }
    }
}

这给: "ReferenceError: Can't find variable: s"

而这按预期工作:

import QtQuick 1.1

Item {
    property string s: "parent-str"
    Item { Component.onCompleted: console.log(s) }
}

时,输出"parent-str"

请看下面的MartinJ的意见。

Answer 1:

这当然不看第一眼直观,但注释掉fromColortoColor在组件根项目及原因变得很明显。 从QML范围文档 ,你可以看到,范围包括:

  • 所有的id的组件中的定义。
  • 局部属性
  • 组件的根对象的属性

GradientStop {}在上面的例子中没有定义局部特性。 根组件确实,他们的性质fromColortoColor决心。 在属性Gradient {}不在范围GradientStop {}在所有。



Answer 2:

也看到这一点:

import QtQuick 1.1

Item {
    property string s: "outer"

    Item {
        property string s: "middle"

        property Item it: Item {
            property string dummy: function() { console.log("(5) s: "+s); "" }()
            Component.onCompleted: console.log("(1) s: " + s)
        }

        Item {
            property string dummy: function() { console.log("(4) s: "+s); "" }()

            function f() {
                console.log("(2) s: " + s)
            }

            Component.onCompleted: {
                console.log("(3) s: " + s)
                f()
            }
        }
    }
}

此代码输出:

(5) s: outer
(4) s: outer
(3) s: outer
(2) s: outer
(1) s: outer

请注意,但是,(给孩子的财产或没有)和任何(Element或JavaScript代码段),我们绑定,“中间”属性没有找到。

因此,名称查找是:

  1. ID的项目或组件中定义(见3)
  2. 本地地产
  3. 顶级项的属性(或部件的情况下,它被定义内联,即使在“组件”的名称被省略,当代表们方便地定义等)。

此外,当一个属性在组件内引用,但不能在其内定义,但它仍然可以在“定制”部件内引入,并且可以看出:

//OverrideInner.qml
import QtQuick 1.1

Item {
    Component.onCompleted: console.log(s)
}

//OverrideOuter.qml
import QtQuick 1.1

Item {
    property string s: "overriden-outer"

    Item {
        property string s: "overriden-middle"

        OverrideInner {
            property string s: "overriden-inner"
        }
    }
}

运行“OverrideOuter.qml”生产:

overriden-inner

再次,看马丁的意见和文档,以澄清此事。 相关的文档有:

  • 声明范围
  • 属性绑定


文章来源: QML component scope puzzle