13.1 动态加载组件(Loading Components Dynamically)
动态加载QML不同组成部分最简单的方法是使用加载元素项(Loader element)。它作为一个占位符项用来加载项。项的加载通过资源属性(source property)或者资源组件(sourceCompontent)属性控制。加载元素项通过给定的URL链接加载项,然后实例化一个组件。
加载元素项(loader)作为一个占位符用于被加载项的加载。它的大小基于被加载项的大小而定,反之亦然。如果加载元素定义了大小,或者通过锚定(anchoring)定义了宽度和高度,被加载项将会被设置为加载元素项的大小。如果加载元素项没有设置大小,它将会根据被加载项的大小而定。
下面例子演示了使用加载元素项(Loader Element)将两个分离的用户界面部分加载到一个相同的空间。这个主意是我们有一个快速拨号界面,可以是数字界面或模拟界面。如下面插图所示。表盘周围的数字不受被加载项影响。
首先,在应用程序中声明一个加载元素项(Loader element)。注意,资源属性(source property)已经被忽略。这是因为资源取决于当前用户界面状态。
Loader {
id: dialLoader
anchors.fill: parent
}
拨号加载器(dialLoader)的父项的状态属性改变元素驱动根据不同状态加载不同的QML文件。在这个例子中,资源属性(source property)是一个相对文件路径,但是它可以是一个完整的URL链接,通过网络获取加载项。
states: [
State {
name: "analog"
PropertyChanges { target: analogButton; color: "green"; }
PropertyChanges { target: dialLoader; source: "Analog.qml"; }
},
State {
name: "digital"
PropertyChanges { target: digitalButton; color: "green"; }
PropertyChanges { target: dialLoader; source: "Digital.qml"; }
}
]
为了使被加载项更加生动,它的速度属性必须根项的速度属性绑定。不能够使用直接绑定来绑定属性,因为项不是总在加载,并且这会随着时间而改变。需要使用一个东西来替换绑定元素(Binding Element)。绑定目标属性(target property),每次加载元素项改变时会触发已加载完成(onLoaded)信号。
Loader {
id: dialLoader
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: analogButton.top
onLoaded: {
binder.target = dialLoader.item;
}
}
Binding {
id: binder
property: "speed"
value: speed
}
当被加载项加载完成后,加载完成信号(onLoaded)会触发加载QML的动作。类似的,QML完成加载以来与组建构建完成(Component.onCompleted)信号。所有组建都可以使用这个信号,无论它们何时加载。例如,当整个用户界面完成加载后,整个应用程序的根组建可以使用它来启动自己。