0%

Loader属性说明

Loader用于动态加载QML组件。可以加载QML文件(使用source属性)或Component对象(使用sourceComponent属性)。

本文: https://www.lovejia.win/blog/article/Loader.html
参考原文:http://doc.qt.io/qt-5/qml-qtquick-loader.html
参考译文:http://blog.csdn.net/sbisyju/article/details/9203173

属性说明

active : bool

此属性是true如果装载程序当前处于活动状态。此属性的默认值为true。
如果装载程序处于非活动状态,更改源或源组件不会导致在启动装载程序之前实例化该项目。
将值设置为inactive将导致加载器加载的任何项目被释放,但不会影响source或sourceComponent。
非活动加载程序的状态始终为Null。

asynchronous : bool

此属性保存组件是否将异步实例化。
当与源属性一起使用时,加载和编译也将在后台线程中执行。
加载异步创建组件在多个框架中声明的对象,并减少动画中出现毛刺的可能性。当异步加载时,状态将更改为Loader.Loading。一旦创建了整个组件,该项目将可用,状态将更改为Loader.Ready。
将此属性的值更改false为异步加载正在进行时将强制立即执行同步完成。这允许开始异步加载,然后在异步加载完成之前必须访问加载程序内容时强制完成。
注意:此属性仅影响对象实例化; 它与通过网络异步加载组件无关。

item : object

此属性保存当前加载的顶级对象。
因为QtQuick 2.0,Loader可以加载任何对象类型。

progress : real

此属性保存从网络加载QML数据的进度,从0.0(无加载)到1.0(完成)。大多数QML文件都很小,所以这个值会迅速从0变为1。

source : url

此属性保存要实例化的QML组件的URL。
因为QtQuick 2.0,Loader能够加载任何类型的对象; 它不限于项目类型。
要卸载当前加载的对象,请将此属性设置为空字符串,或将sourceComponent设置为undefined。设置source为新的URL也会导致由上一个URL创建的项目被卸载。

sourceComponent : Component

此属性保存要实例化的组件。
要卸载当前加载的对象,请将此属性设置为undefined。

status : enumeration

此属性保存QML加载的状态。它可以是以下之一:
Loader.Null - 加载程序处于非活动状态或没有设置QML源
Loader.Ready - 已加载QML源
Loader.Loading - 当前正在加载QML源
Loader.Error - 加载QML源时发生错误
使用此状态以某种方式提供更新或响应状态更改。

信号说明

loaded()

当状态变为Loader.Ready或成功初始加载时,发出此信号。
相应的处理程序是onLoaded。

方法说明

object setSource(url source, object properties)

创建一个给定的对象实例源组件,具有给定的性质。在性能参数是可选的。一旦加载和实例化完成,实例将可通过item属性访问。
如果active属性false在调用此函数时,则不会加载给定的源组件,但将会缓存源和初始属性。当加载器被激活时,将创建具有初始属性集的源组件的实例。
以这种方式设置组件实例的初始属性值不会触发任何关联的行为。

注意:如果在调用此函数之后但在设置加载程序活动之前更改了source或sourceComponent,那么将清除缓存的属性。

功能简述

Loader用于动态加载QML组件。
Loader可以加载QML文件(使用source属性)或Component对象(使用sourceComponent属性)。它有助于延迟组件的创建,直到需要它:例如,当按需创建组件时,或者出于性能原因不应该不必要地创建组件时。
如果source或sourceComponent发生更改,则以前实例化的任何项目都将被销毁。将源设置为空字符串或设置sourceComponent以undefined销毁当前加载的对象,释放资源并使加载程序为空。

下面的例子是一个加载器,当MouseArea被点击时加载“Page1.qml”作为组件:

1
2
3
4
5
6
7
8
9
10
11
import QtQuick 2.0
Item {
width: 200; height: 200

Loader { id: pageLoader }

MouseArea {
anchors.fill: parent
onClicked: pageLoader.source = "Page1.qml"
}
}

如果源组件不是项类型,Loader不应用任何特殊的大小调整规则。下面的例子
Loader应用以下大小调整规则:
如果未为装载程序指定显式大小,则一旦组件加载,装载程序将自动调整大小为加载项目的大小。
如果通过设置宽度,高度或通过锚定显式指定装载程序的大小,则装载的项目将被调整为装载程序的大小:
sizeloader.qml红色矩形的大小将根据根项目的大小:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import QtQuick 2.0

Item {
width: 200; height: 200

Loader {
// 将Loader 的大小明确设置为父项目大小
anchors.fill: parent
sourceComponent: rect
}

Component {
id: rect
Rectangle {
width: 50
height: 50
color: "red"
}
}
}

sizeitem.qml红色矩形将为50x50,居中位于根项目中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import QtQuick 2.0
Item {
width: 200; height: 200

Loader {
// 将装载器放置在父锚的中心位置
anchors.centerIn: parent
sourceComponent: rect
}

Component {
id: rect
Rectangle {
width: 50
height: 50
color: "red"
}
}
}

使用连接类型可以接收从加载对象发出的任何信号。例如,以下application.qml加载MyItem.qml,并且能够message通过Connections对象从加载的项目接收信号:
application.qml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import QtQuick 2.0
Item {
width: 100; height: 100

Loader {
id: myLoader
source: "MyItem.qml"
}

Connections {
target: myLoader.item
onMessage: console.log(msg)
}
}

MyItem.qml:

1
2
3
4
5
6
7
8
9
10
11
12
import QtQuick 2.0
Rectangle {
id: myItem
signal message(string msg)

width: 100; height: 100

MouseArea {
anchors.fill: parent
onClicked: myItem.message("clicked!")
}
}

Loader是一个焦点范围。它的focus属性必须设置为它true的任何子级才能获得活动焦点。加载的项目中接收的任何键事件都应该被接受,因此它们不会传播到装载程序。
例如,当点击MouseArea时,将application.qml加载KeyReader.qml以下内容。注意focus属性设置true为Loader以及动态加载对象中的Item;一旦KeyReader.qml加载,它接受键事件和集合event.accepted,true以便事件不会传播到父矩形。
application.qml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import QtQuick 2.0
Rectangle {
width: 200; height: 200

Loader {
id: loader
focus: true
}

MouseArea {
anchors.fill: parent
onClicked: loader.source = "KeyReader.qml"
}

Keys.onPressed: {
console.log("Captured:", event.text);
}
}

KeyReader.qml:

1
2
3
4
5
6
7
8
9
10
11
import QtQuick 2.0
Item {
Item {
focus: true
Keys.onPressed: {
console.log("Loaded item captured:",
event.text);
event.accepted = true;
}
}
}

在下面的示例中,ListView插入到index上下文中的上下文属性将无法访问Text,因为Loader将在创建上下文时使用创建上下文作为父上下文,并且不引用该上下文链中的任何内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import QtQuick 2.0
Item {
width: 400
height: 400

Component {
id: myComponent
Text { text: index } //fails
}

ListView {
anchors.fill: parent
model: 5
delegate: Component {
id: delegateComponent
Loader {
sourceComponent: myComponent
}
}
}
}

在这种情况下,我们可以移动组件在线:

1
2
3
4
5
6
7
delegate: Component {
Loader {
sourceComponent: Component {
Text { text: index }
}
}
}

进入一个单独的文件:

1
2
3
4
5
delegate: Component {
Loader {
source: "MyComponent.qml"
}
}

或者将所需的信息显式地设置为Loader的属性(这是因为Loader将自身设置为它正在加载的组件的上下文对象):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Item {
width: 400
height: 400

Component {
id: myComponent
Text { text: modelIndex }
}

ListView {
anchors.fill: parent
model: 5
delegate: Component {
Loader {
property int modelIndex: index
sourceComponent: myComponent
}
}
}
}

下面示例为了避免看到正确加载的项目visible:

1
2
3
4
5
Loader {
source: "mycomponent.qml"
asynchronous: true
visible: status == Loader.Ready
}

以下示例sourceComponent保存要实例化的组件:

1
2
3
4
5
6
7
8
9
Item {
Component {
id: redSquare
Rectangle { color: "red"; width: 10; height: 10 }
}

Loader { sourceComponent: redSquare }
Loader { sourceComponent: redSquare; x: 10 }
}

以下示例使用status保存QML加载的状态以某种方式提供更新或响应状态更改:
触发状态更改:

1
State { name: 'loaded'; when: loader.status == Loader.Ready }

实现onStatusChanged信号处理程序:

1
2
3
4
Loader {
id: loader
onStatusChanged: if (loader.status == Loader.Ready) console.log('Loaded')
}

绑定到状态值:

1
Text { text: loader.status == Loader.Ready ? 'Loaded' : 'Not loaded' }

注意:如果源是本地文件,状态将初始为就绪(或错误)。虽然在这种情况下没有onStatusChanged信号,onLoaded仍然会被调用。

以下示例object setSource(url source, object properties)方法:
ExampleComponent.qml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import QtQuick 2.0
Rectangle {
id: rect
color: "red"
width: 10
height: 10

Behavior on color {
NumberAnimation {
target: rect
property: "width"
to: (rect.width + 20)
duration: 0
}
}
}

example.qml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import QtQuick 2.0
Item {
Loader {
id: squareLoader
onLoaded: console.log(squareLoader.item.width);
// prints [10],而不是[30]
}

Component.onCompleted: {
squareLoader.setSource("ExampleComponent.qml",
{ "color": "blue" });
// 将在完成时触发onLoaded代码。
}
}

注意:如果在调用此函数之后但在设置加载程序活动之前更改了source或sourceComponent,那么将清除缓存的属性。

------本文结束    感谢阅读------
你打赏你的,我分享我的!