QML中Loader元素的使用

Loader元素用来动态加载可见的QML组件。它可以用来加载一个QML文件(使用source属性),也可以用来加载一个组件(Component)对象(使用sourceComponent属性)。这个元素最有用的地方是它能在qml组件需要的时候再创建,即延迟创建QML的时间,提高程序的性能。

 main.qml  
   ------------------------------------  
   import QtQuick 1.0  
 
   Item {  
   property bool isFirst : false;  
   width: 200  
   height: 200  
 
   Loader {  
   id: pageLoader  
   }  
 
   MouseArea {  
   anchors.fill: parent  
   onClicked: changePage();  
   }  
 
   function changePage() {  
   if(isFirst) {  
   pageLoader.source = "Page1.qml"  
   } else {  
   pageLoader.source = "Page2.qml"  
   }  
 
   isFirst = !isFirst;  
   }  
 
   }  
 
 
   Page1.qml  
   -------------------------------------  
   import QtQuick 1.0  
 
   Rectangle {  
   width: 100  
   height: 62  
   Text {  
   anchors.centerIn: parent  
   text: "Page1 Test"  
   }  
   }  
 
 
   Page2.qml  
   ---------------------------------------  
   import QtQuick 1.0  
 
   Rectangle {  
   width: 100  
   height: 62  
   Text {  
   anchors.centerIn: parent  
   text: "Page1 Test"  
   }  
   }

上面的代码就能界面在Page1和Page2之间切换了,别忘了还能使用sourceComponent属性

 main.qml  
   --------------------------------------  
   import QtQuick 1.0  
 
   Item {  
   property bool isFirst : false;  
   width: 200  
   height: 200  
 
   Loader {  
   id: pageLoader  
   sourceComponent: rect  
   }  
 
   MouseArea {  
   anchors.fill: parent  
   onClicked: changePage();  
   }  
 
   function changePage() {  
   if(isFirst) {  
   pageLoader.source = "Page1.qml"  
   } else {  
   pageLoader.source = "Page2.qml"  
   }  
 
   isFirst = !isFirst;  
   }  
 
   Component {  
   id: rect  
   Rectangle {  
   width: 200  
   height: 50  
   color: "red"  
   Text {  
   text: "Default Page"  
   anchors.fill: parent  
   }  
   }  
   }  
   }

已经加载的item可以通过item属性来访问。Loader与其他可见item一样,需要设置位置的大小才可见。一旦组件被加载,Loader会自动设置组件的大小。当source或是sourceComponent属性发生变化时,之前加载的item都会被销毁,将source或是sourceComponent属性设置成空字符串可以销毁当前已经加载的item,释放Loder所占用的资源,接下来我们将演示如何从加载的ITEM中接受信号

Item {  
   property bool isFirst : false;  
   width: 200  
   height: 200  
 
   Loader {  
   id: pageLoader  
   source: "Page1.qml"  
   }  
 
 
   Connections {  
   target: pageLoader.item  
   onMessage: console.log(msg);  
   }  
 
}  
 
Page1.qml  
----------------------------------------------  
import QtQuick 1.0  
 
Rectangle {  
   id: myItem  
   signal message(string msg)  
   width: 100; height: 100  
 
   MouseArea {  
   anchors.fill: parent  
   onClicked: myItem.message("clicked!");  
   }  
}

最后我们来看下如何是loader的子ITEM获得焦点,Loader是一个焦点区域,如果想让Loader的子item获得活动的焦点,必须将Loader的focus属性设置为真。Loader中加载的组件应该接受任何收到的键盘事件,这样键盘事件就不会抛给Loader处理。在下面的例子中,当单击MouseAre时,aapplication.qml加载KeyReader.qml文件。注意Loader的focus属性和KeyReader.qml中的item的focus属性均设置为真

KeyReader.qml:
import Qt 4.7
 
 Item {
   Item {
   focus: true
   Keys.onPressed: {
   console.log("Loaded item captured:", event.text);
   event.accepted = true;
   }
   }
 }
 
application.qml:
import Qt 4.7
 
 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被加载,它会接受所有的键盘事件,将event.accepted属性设置为真,这样事件就不会上抛给Rectangle处理。