- 細節描述:
- 功能
- 動態加載QML組件
- 加載對象可以爲通過URL加載的qml文件,也可以是加載對象組件
- 用於當組件被調用時才創建
- 在處於性能方面考慮下,組件在某些情況下無需被創建的情形下使用該QML對象
- 當使用“item”屬性後loader對象才能夠被訪問
- loader加載其他組件或者其他qml文件後,先前已經實例化了的組件或者qml文件的資源將會被清理
- 利用以上的特性可以將loader的source屬性設置爲空的string或者設置sourceComponent爲undefined將會釋放資源空間和離開空的Loader
- Loader的尺寸特性(Loader sizing behavior)
若source Component 加載的是非Item類型時,Loader不應用任何指定的尺寸規則。當用於加載可用類型時,Loader應用如下的尺寸規則:
- 如果Loader沒有明確指定尺寸,Loader將會自動地根據加載的組件的Loader Item尺寸來調整大小。
- 如果Loader設置大小規則(height or anchoring)來明確指定尺寸大小,Loader將會根據該尺寸從新調整尺寸大小
- 功能
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"
}
}
}
//由於Loader明確指定尺寸大小,因此Loader將會根據parent的大小來調整Loader的大小;
再來看一個未明確指定大小的例子:
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"
}
}
}
//由於沒有明確指定Loader的大小,因此Loader將會根據加載的組件的尺寸規則來調整加載組件的大小。
結論:Loader的尺寸規則優先根據Loader明確指定的尺寸來調整,否則根據加載的組件或者qml文件的尺寸規則來調整顯示大小
- Receiving signals from loaded objects(從loaded對象中接受信號)
任何從loaded中發射出來的信號可以使用Connections類來接收。舉個例子:以下application.qml 加載Myitem.qml 並且可以通過connections對象來接收來自Loaded Item emit 的message信號
//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)
}
}
//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中的函數
- 聚焦和鍵盤事件(Focus and key events)
Loader 是一個聚焦的範圍,它的“focus”屬性必須被設置爲true,這樣它的子類才能夠獲取它的活動的焦點;在loaded Item中的任何一個鍵盤事件應該也可以被接收,這樣纔不會被傳播到Loader。
舉個例子,以下application.qml 在鼠標點擊後加載 KeyReader.qml
注意和動態加載的item一樣,Loader的focus屬性也設置爲true
//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);
}
}
//KeyReader.qml
import QtQuick 2.0
Item {
Item {
focus: true
Keys.onPressed: {
console.log("Loaded item captured:",
event.text);
event.accepted = true;
}
}
}
一旦KeyReader.qml 被加載後,它將接收鍵盤事件,設置event.accepted 爲true 這樣鍵盤事件將不會被傳播到父類的Rectangle
自從QtQuick 2.0 後 Loader可以加載不可見的組件。
- 使用視圖代理的Loader(Using a Loader within a view delegate)
在一些希望使用視圖代理的Loader來提高代理加載的性能時,在大多數情況下這種方法很有效,但有一個重要的問題:
在以下的例子中,通過ListView插入的index這個上下文屬性進入代理的組件的上下文關係中將訪問不到Text;原因是:Loader在實例化時,將會使用myComponent 創建的上下文關係作爲父類的上下文關係,並且此時index在上下文鏈路中將不會指向任何東西。
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
}
}
}
}
這種情況下我們可以這樣修改:
將加載的組件直接包含在Loader中這樣實例化時,Loader的父類的上下文關係鏈路將會依靠Componect 創建的context,這樣index將會指向Component的index
delegate: Component {
Loader {
sourceComponent: Component {
Text { text: index } //okay
}
}
}
或者可以將要加載的組件分離開來:
delegate: Component {
Loader {
source: "MyComponent.qml" //okay
}
}
或者在Loader中將index這種context的屬性記錄下來。避免Loader依靠所加載的組件生成的context來獲取context的屬性。
Item {
width: 400
height: 400
Component {
id: myComponent
Text { text: modelIndex } //okay
}
ListView {
anchors.fill: parent
model: 5
delegate: Component {
Loader {
property int modelIndex: index
sourceComponent: myComponent
}
}
}
}
總結: 在使用Model-view-delegate 提高組件性能時,要注意Loader的上下文關係(context)將會依靠加載的組件生成的context,這樣可能會導致加載的組件生成的上下文關係中沒有context特定的屬性或者指向未知位置。
屬性:
active : bool
Loader當前是激活時該屬性爲true,該屬性默認值爲true
如果Loader 不激活,改變source和sourceComponent 的值後將不會依據Item實例化Loader,除非激活Loader。
設置爲非激活,將註銷加載器加載的任何Item,當不會對source或者sourceComponent屬性產生任何作用。
非激活的Loader的status屬性將總會是“null”asynchronous : bool
這個屬性決定是否一步實例化組件
當我們和source屬性同時用時,加載和編譯的工作將會都在後臺線程中執行。
Loading 將會異步跨越多個幀來創建由組件定義的對象,這樣可以減少動畫過渡產生的毛刺
異步加載時,Loader的狀態將會變爲Loader.Loading
一旦組件的實體被創建後,Item將會可用的並且狀態將會變爲Loader.Ready.
爲了避免看到Items 逐步被加載,可以適當地設置visible這個屬性,比如Loader { source: "mycomponent.qml" asynchronous: true visible: status == Loader.Ready } //異步加載完成後,Loader纔會被激活
注意這個屬性在object實例化過程中才有效,這個屬性和通過網絡異步加載組件無關
item : object
這個屬性控制當前加載器的頂級對象
- progress : real
這個屬性控制從網絡中加載QML組件的進展,改值從0.0(沒有加載)到1.0(加載完成),大多數QML文件都是很小的,因此改值快速地在0.0和1.0之間變化
- progress : real
source : url
控制將要實例化的QML組件的URL
sourceComponect : Componect
控制將要實例化的組件
Item {
Component {
id: redSquare
Rectangle { color: "red"; width: 10; height: 10 }
}
Loader { sourceComponent: redSquare }
Loader { sourceComponent: redSquare; x: 10 }
}status : enumeration
QMl 加載的狀態,該狀態是以下其中的一項:
- Loader.Null :Loader沒有激活或者QML source 沒有設置
- Loader.Ready :QML source已經被加載完成。
- Loader.Loading :QML source目前正在加載。
- Loader.Error :加載QML source時發生錯誤。
發射的信號
- loader()
當status 變爲Loader.Ready後或者成功初始化加載後將會發射該信號
相應的處理程序是OnLoaded- loader()
- 使用方法:
- object setSource(url source, object properties)