QML component scope puzzle

人盡茶涼 提交于 2019-12-04 18:37:34

问题


Take this code:

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 }
    }
}

Why exactly does the Gradient pick its fromColor and toColor properties from the enclosing element?

Where is this documented (at least within source code comments, better within the official docs)?

Note: this "QML obfuscation example is from Girish Ramakrishnan's talk Qt Quick Best Practices and Design Patterns (rewind to 25th minute), where he does say that the thing is extremely complicated and has to with component scope and like that, but has no time to explain why.

[UPDATE]

So, as MartinJ tells below, the top-level component in the element-property (not only element-child) hierarchy has its properties visible to all properties however deep nested, with the precedence being of that properties' properties, and all properties of "intermediate" items not seen at all.

Here's a small example:

import QtQuick 1.1

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

This gives: "ReferenceError: Can't find variable: s"

And this works as expected:

import QtQuick 1.1

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

, outputting "parent-str".

Please see MartinJ's comments below.


回答1:


This certainly doesn't look intuitive at first glance, but comment out fromColor and toColor in the component root item and the reason becomes apparent. From the QML Scope docs you can see that the scope includes:

  • all of the id's defined within the Component.
  • local properties
  • the properties of the root object of the Component

A GradientStop {} in the example above has no local properties defined. The root component does, and they are the properties that fromColor and toColor resolve to. The properties in Gradient {} are not in the scope of the GradientStop {} at all.




回答2:


Also see this:

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()
            }
        }
    }
}

this code outputs:

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

Note, that however (to the Children property or not) and whatever (an Element or a javascript code snippet) we bind, the "middle" property is never found.

The name lookup thus is:

  1. id's defined within the Item or Component (see 3)
  2. Local properties
  3. Top-level Item's properties (or Component, in case it's defined inline, even when the "Component" name is omitted, like when delegates are conveniently defined).

Also, when a property is referenced within the component, but not defined within it, it still can be introduced within the "customized" component, and be seen:

//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"
        }
    }
}

Running "OverrideOuter.qml" produces:

overriden-inner

Again, see Martin's comments and the docs to clarify the matter. The relevant docs are:

  • Declarative Scope
  • Property Binding


来源:https://stackoverflow.com/questions/11339719/qml-component-scope-puzzle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!