本篇文章是对来自🤝BiliBili-清晨与猫鱼的QML教程的学习笔记,原视频链接👇
https://www.bilibili.com/video/BV1Ay4y1W7xd?spm_id_from=..search-card.all.click&vd_source=4079f59f2068471b4d379822052e0270


Loader

一、描述

Loader用于动态加载QML组件。
加载器可以加载QML文件(使用source属性)或Component对象(使用sourceComponent属性)。它有助于将组件的创建延迟到需要时:例如,应该根据需要创建组件时,或者出于性能原因不应该不必要地创建组件时。

下面是加载“Page1”的Loader。当单击MouseArea时,将其作为组件:

1
2
3
4
5
6
7
8
9
10
11
12
import QtQuick 2.0

Item {
width: 200; height: 200

Loader { id: pageLoader }

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

可以使用item属性访问加载的对象。
如果源或sourceComponent发生变化,任何先前实例化的项都会被销毁。将source设置为空字符串或将sourceComponent设置为undefined会破坏当前加载的对象,释放资源并使Loader为空。

二、加载程序大小调整行为

如果源组件不是Item类型,则Loader不会应用任何特殊的大小规则。当用于加载可视类型 >时,Loader应用以下大小规则:

  • 如果未为Loader指定显式大小,则加载组件后,Loader会自动调整为已加载项的大小。
  • 如果加载器的大小是通过设置宽度、高度或锚定来显式指定的,则加载的项目将被调整为加载器的大小。

在这两种情况下,项目和Loader的大小是相同的。这确保了对Loader的锚定等同于对加载项的锚定。

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

Item {
width: 200; height: 200

Loader {
// Explicitly set the size of the
// Loader to the parent item's size
anchors.fill: parent
sourceComponent: rect
}

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

红色矩形将调整为根项的大小。

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

Item {
width: 200; height: 200

Loader {
// position the Loader in the center
// of the parent
anchors.centerIn: parent
sourceComponent: rect
}

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

红色矩形将是50x50,居中于根项。

三、从加载对象接收信号

从加载对象发出的任何信号都可以使用Connections类型接收。
例如,下面的应用程序。qml加载MyItem。qml,并且能够通过Connections对象接收来自加载项的消息信号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
application.qml
import QtQuick 2.0

Item {
width: 100; height: 100

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

Connections {
target: myLoader.item
onMessage: console.log(msg)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
MyItem.qml
import QtQuick 2.0

Rectangle {
id: myItem
signal message(string msg)

width: 100; height: 100

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

或者,自从MyItem。qml是在Loader的作用域中加载的,它也可以直接调用Loader或它的父Item中定义的任何函数。

四、焦点和关键事件

Loader是一个焦点作用域。它的任何子焦点必须将其focus属性设置为true才能获得活动焦点。(请参阅Qt Quick中的键盘焦点了解更多细节。)在加载项中接收到的任何关键事件也应该被接受,这样它们就不会传播到Loader。

例如,下面的应用程序。qml加载KeyReader。当鼠标区域被点击时。注意,对于Loader和动态加载对象中的Item, focus属性都被设置为true:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

application.qml
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);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
KeyReader.qml
import QtQuick 2.0

Item {
Item {
focus: true
Keys.onPressed: {
console.log("KeyReader captured:",
event.text);
event.accepted = true;
}
}
}

一旦KeyReader。加载QML后,它接受键事件并设置事件。接受为true,这样事件就不会传播到父矩形。
从QtQuick 2.0开始,Loader也可以加载非可视化组件。

五、未完待续