Loader QML Type

  • 細節描述:
    • 功能
      • 動態加載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之間變化
    • 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


  • 使用方法:
    • object setSource(url source, object properties)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章