QML概念及框架--QML的作用域

    QML屬性綁定、內聯函數和導入的JavaScript文件都運行在一個JavaScript作用域。作用域控制表達式可以訪問哪些變量,以及當兩個或多個名字衝突時,哪個,哪個變量優先。因爲JavaScript的內建作用域機制非常簡單,QML對其進行了加強,使其更加自然的適應QML語言的擴展。

    1. JavaScript作用域

    QML的作用域擴展並沒有干擾JavaScript本身的作用域。

QtObject {
    property int a: 3
    property int b: 9
    
    function addConstant(b) {   //函數處理結果與QML對象的a和b屬性無關
        var a = 13
        return b + a;
    }
}
    QML遵循JavaScript一般的作用域規則,在應用綁定時也是這樣。

QtObject {
    property int a
    
    a: {var a = 12; a;} //給a屬性綁定一個值12
}
    每個在QML中的JavaScript表達式、函數或者文件都有它們任意一個裏面聲明的局部變量都不會和在另一個裏面聲明的局部變量衝突。

2. 元素名稱和導入的JavaScript文件

    QML文件包含了導入語句來定義元素名稱和JavaScript文件,使其在文件中可見。除了在QML聲明時使用,在訪問附加屬性和枚舉值時JavaScript代碼也會使用元素名稱。在QML中import會影響每一個屬性綁定、QML文件中的JavaScript函數以及那些嵌套的內聯組件。

import QtQuick 2.4
import "code.js" as Code

ListView {
    snapMode: ListView.SnapToItem
    
    delegate: Component {
        Text {
            elide: Text.ElideMiddle
            text:"A really, really long string that will require eliding."
            color: Code.defaultColor()
        }
    }
}
3. 綁定作用域對象

    屬性綁定是在QML中最常見的JavaScript應用,關聯了一個JavaScript表達式的結果和對象的一個屬性。綁定對象所屬的對象被稱爲綁定的作用域對象。QML爲JavaScript引入了一個更加結構化、面向對象的方式,因此不再需要使用JavaScript的this屬性。

     當從綁定中訪問附加屬性是要非常小心,因爲它們會與作用域對象交互。從概念上講,附加屬性在所有對象上都存在,即使它們只對這些對象的子集有影響。因此,非限定的附加屬性的讀取,總會得到作用域對象附加屬性值。如PathView元素會向它的委託附加一個插值屬性,這個插值屬性依賴於在路徑中具體的位置。因爲PathView只會向委託的根元素附件這些屬性,任何的子元素要訪問這些屬性都要明確限定根元素。

PathView {
    delegate: Component{
        Rectangle {
            id: root
            Image {
                //如果Image元素忽略了root前綴,
                //那麼它就會在無意中訪問在它自己上的未設置的PathView.scale附加屬性
                scale: root.PathView.scale 
            }
        }
    }
}
4. 組件作用域

    在QML文件中的每一個組件都定義了一個邏輯作用域。每一個文件都至少有一個根組件,但是也可以擁有其他的內聯自組件。組件的作用域是組件內的對象id和組件的根元素的屬性的聯合。

Item {
    property string title

    Text {
        id: titleElement
        text: "<b>" + title + "</b>"
        font.pixelSize: 22
        anchors.top: parent.top
    }
    Text {
        text: titleElement.text
        font.pixelSize: 18
        anchors.bottom: parent.bottom
    }
}
   ID在QML中明確指定,所以它們總是優先於其他屬性名稱。如果在此例子中綁定的作用域對象也有一個titleElement屬性,那麼依然優先考慮id爲titleElement,而不會把它當作一個屬性。

5. 組件實例的層次

    在QML中,組件實例將它們的作用域關聯在一起形成了 一個作用域層次。組件實例可以直接訪問其祖先的作用域。例如,使用內聯子組件時, 它的組件作用域隱式的設置爲了氣外部組件作用域的孩子。

Item {
    property color defaultColor: "blue"

    ListView {
        delegate: Component {
            Rectangle{
                color: defaultColor
            }
        }
    }
}
    組件實例層次允許委託組件的實例訪問Item元素的defaultColor屬性。當然,如果委託組件也有一個名爲defaultColor的屬性,那麼將會優先訪問它。

    組件實例作用域層次可以擴展到非內聯的組件。QML是一個動態作用域語言,依賴於在哪裏被使用。

//TitlePage.qml文件
import QtQuick 2.4

Item {
    property string title
    
    TitleText {
        size: 22
        anchors.top: parent.top
    }
    
    TitleText {
        size: 18
        anchors.bottom: parnt.bottom
    }
}
//TtileText.qml文件
import QtQuick 2.4

Text {
    property int size
    text: "<b>" + title + "</b>"
    font.pixelSize: size
}
    動態作用域是非常強大的,但是必須謹慎使用以避免QML代碼的行爲變得難以預料。一般情況下,它只用於兩個組件已經通過其他方法緊密耦合的情況下。當構建可重用組件是,最好使用屬性接口。

//TitlePage.qml文件
import QtQuick 2.4

Item {
    id: root
    property string title
    
    TitleText {
        size: 22
        anchors.top: parent.top
    }
    
    TitleText {
       title: root.title
        size: 18
        anchors.bottom: parnt.bottom
    }
}
//TtileText.qml文件
import QtQuick 2.4

Text {
    propterty string title
    property int size

    text: "<b>" + title + "</b>"
    font.pixelSize: size
}
6. JavaScript全局對象

    除了JavaScript全局對象的所有屬性以外,QML還添加了一些自定義的擴展來更容易完成UI或者QML指定的任務。qml通過不允許元素、id和屬性名稱與全局對象的屬性同名來防止衝突。


  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章