如何使用Loader来动态载入一个基于item的Component

来源:互联网 发布:linux运维开发 编辑:程序博客网 时间:2024/06/16 20:34

QML中的Loader是用来动态地载入一个QML的Component。它可以用来载入一个QML文件(使用它的source属性)。它也可以载入一个Component(使用它的sourceComponent属性)。它适合在需要载入一个Component时才载入它,这样避免资源的浪费。它可以动态地载入按需求在需要的时候创建我们需要的Component。更多阅读,可以参照:http://qt-project.org/doc/qt-4.8/qml-loader.html。


1)动态载入一个Component


我们首先来创建我们一个基本的应用。这里我们使用一个"App with Simple UI"的模版。我们首先创建一个称作为"filearray.js"的javascript文件,如下:

var filearray = [                    ["images/fall1.jpg", "First image"],                    ["images/fall2.jpg", "Second image"],                    ["images/fall3.jpg", "Three image"],                    ["images/fall4.jpg", "Fourth image"]                ];

这里创建了一个二维的数组。为了我们能够在应用中使用。同时,我们在"main.qml"中也创建一个Component。这样它可以在我们的应用中动态地产生。代码如下:

        Component {            id: imageText            Rectangle {                id:top                anchors.fill: parent                Image {                    id:innerImage                    anchors.top: parent.top                    anchors.topMargin:30                    anchors.horizontalCenter: parent.horizontalCenter                    width:parent.width*0.8;                    height: parent.height*0.8                    source:root.currentImage                }                Text{                    id:answer                    anchors.top:innerImage.bottom                    anchors.topMargin:30                    horizontalAlignment: Text.AlignHCenter                    width:parent.width;                    text:root.currentText                }            }       
这个Component非常简单。上面使用了一个Image,下面是一个Text。这两个item的内容是从root控件中的两个property中获得。我们希望这root中的这两个property改变时他们的内容也可以改变。

   Page {        id: root;        title: i18n.tr("QML Loader")        property int index: 0        property string currentImage        property string currentText:" "

同时,为了说明问题,我们也设计了一个timer。当这个timer每次timeout时,我们希望我们的loader:

        Loader {            id: loader            anchors.fill: parent            anchors.centerIn:parent        }

的"sourceComponent"每次都能发生改变,以使得UI得到变化。这里有趣的是,我们也可以为Loader定义它的大小:

  • 如果没有定义Loader的大小的话,Loader将会自动地适配到Component的大小尺寸(当component完成装载以后)
  • 如果Loader的大小已经被定义的话,当component完成装载后,component的尺寸将自动被适配到Loader的尺寸
    function timeout() {        console.log("root.index" + root.index);        console.log(FileExt.filearray[root.index][0]);        root.currentImage = FileExt.filearray[root.index][0];        root.currentText = FileExt.filearray[root.index][1];        loader.sourceComponent = imageText;        root.index++;        if ( root.index === FileExt.filearray.length) {            root.index = 0;        }    }

        Timer {            id: timer            interval: 3000            onTriggered: {                timeout();            }            repeat: true            triggeredOnStart: true        }

运行的效果图如下:



我们可以看到画面中的每三秒改变一次。每一次都是一个新的Component,而不是同一个Component不变,只是其中的属性发生改变。Loader很适用于在不同的场景中装载不同的component,比如在不同的菜单中,装载不同的component,以显示不同的UI。Qt SDK很多的例程就是这样写的!

整个例程的代码在如下地址找到:

bzr branch lp:~liu-xiao-guo/debiantrial/loaderqml

2)使用Loader载入qml文件


在下面的例程中,我们来完成一个使用Loader来载入qml文件。我们来做一个类似wizard的东西。当第一个页面显示完后,紧接着按下一个按钮,进入下一个页面。我们首先来创建一个简单的"App with Simple UI"的模版应用,然后,修改main.qml文件:

import QtQuick 2.0import Ubuntu.Components 1.1import "components"MainView {    // objectName for functional testing purposes (autopilot-qt5)    objectName: "mainView"    // Note! applicationName needs to match the "name" field of the click manifest    applicationName: "com.ubuntu.developer.liu-xiao-guo.wizard"    //automaticOrientation: true    // Removes the old toolbar and enables new features of the new header.    useDeprecatedToolbar: false    width: units.gu(100)    height: units.gu(75)    Page {        id: root        title: i18n.tr("Wizard")        Loader {            z: 1            id: main            anchors.fill: parent        }        Image {            source: "images/fall1.jpg"            anchors.fill: parent        }        Button {            anchors.right: parent.right            anchors.bottom: parent.bottom            anchors.bottomMargin: 20            anchors.rightMargin: 20            text: "Go to Page 1"            onClicked: {                main.source = "Page1.qml"                console.log("Clicked in main")            }        }        Connections {            target:main.item            onHandlerLoader:{                console.log("Something happened!")            }        }    }}


这里我们定义了一个叫做main的Loader。当我们点击按钮”Go to Page 1"时,我们使用它来装载另外一个页面“Page1.qml"。注意我们在这里设置它的"z" order值为"1”。同时,我们也可以通过如下的Connections来接受来自main Loader的一些signal来做我们所需要的一些处理。
        Connections {            target:main.item            onHandlerLoader:{                console.log("Something happened!")            }        }

在我们的Page1.qml文件中,我们设计如下:

import QtQuick 2.0import Ubuntu.Components 1.1Rectangle {    id:page1    anchors.fill: parent    signal handlerLoader;    Loader{        z: 2        id:loader        anchors.fill: parent    }        Image {        source: "images/fall2.jpg"        anchors.fill: parent    }    Button {        anchors.right: parent.right        anchors.bottom: parent.bottom        anchors.bottomMargin: 20        anchors.rightMargin: 20        text: "Go to Page 2"        onClicked: {            loader.source = "Page2.qml"            handlerLoader();        }    }}

在这里,我们定义了另外一个Loader, 并且设置它的“z” order值为2,使一个画面得它可以覆盖以前的页面。我们也尝试定义了一个signal "handlerLoader"。这样我们可以使得前一个面可以的得到一个响应。我们可以把我们想要的信号通过这样的方式发送出去,让需要对它感兴趣的代码利用它。

运行我们的程序,结果如下:

       

代码在如下的地址可以找到:

bzr branch lp:~liu-xiao-guo/debiantrial/wizard

0 0
原创粉丝点击