在QML中利用Javascript动态生成画面

185 篇文章 7 订阅
137 篇文章 1 订阅

在这篇文章中介绍如何使用Javascript来动态生产画面。 我们在先前的例子中“如何使用QML动态产生Component来完成我们的气球游戏 (2)”已经对动态生产QML做了一些描述。也许那个项目比较复制,现在我来用一些简单的例子来说明一下,这样更加直观。更多的说明可以参阅文章“Dynamic QML Object Creation from JavaScript”。


1)创建我们的动态QML文件


这个文件将被用来被Javascript来动态生产。这是一个模版尽管每次生成的object的属性可能会不一样。

dynamic-image.qml


import QtQuick 2.0

Image {
    width: 400
    height: 225

    source: "images/image1.jpg"

    Image {
        id: overlay

        anchors.fill: parent

        source: "images/image2.jpg"

        opacity: 0;
        Behavior on opacity { NumberAnimation { duration: 300 } }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            if (overlay.opacity === 0)
                overlay.opacity = 1;
            else
                overlay.opacity = 0;
        }
    }
}


这是一个很简单的QML文件。它显示了一个画面,当我们点击画面时,overlay中的画面将会交叉显示或隐藏。



2)创建动态生产QML Object的Javascript


create-component.js


var component;

function createImageObject(x, y) {
    component = Qt.createComponent("dynamic-image.qml");
    if (component.status === Component.Ready || component.status === Component.Error)
        finishCreation(x, y);
    else
        component.statusChanged.connect(finishCreation);
}

function finishCreation(x, y) {
    if (component.status === Component.Ready)
    {
        var image = component.createObject(container, {"x": x, "y": y, width: 300, height:200});
        if (image == null)
            console.log("Error creating image");
    }
    else if (component.status === Component.Error)
        console.log("Error loading component:", component.errorString());
}


这个文件被用来动态生产我们所需要的QML Object。它采用的模版就是我们在上一节中所使用的“dynamic-image.qml”。我们可以设置它的位置参数。当然我们也可以设置它的其它的属性。这里的“container”是我们希望被生产的QML Object所希望放置的位置,也就是它的“父亲”。


3)在QML代码中调用Javascript来生产QML object


import QtQuick 2.0
import Ubuntu.Components 1.1
import "create-component.js" as ImageCreator

/*!
    \brief MainView with a Label and Button elements.
*/

MainView {
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "dynamicqml.liu-xiao-guo"

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(60)
    height: units.gu(85)

    Page {
        id: root
        title: i18n.tr("dynamicqml")
        property int position: 0

        Flickable {
            width: parent.width
            height: parent.height
            clip:true
            contentHeight: container.childrenRect.height

            Column {
                id: container
                anchors.centerIn: parent
            }
        }

        Row {
            anchors.bottom: parent.bottom
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottomMargin: units.gu(1)
            spacing: units.gu(1)

            Button {
                text: "Create New"

                onClicked: {
                    ImageCreator.createImageObject(0, root.position);
                    root.position += 200;
                }
            }

            Button {
                text: "Create from string"

                onClicked: {
                   var newObject = Qt.createQmlObject('import QtQuick 2.0;
                        Image {source: "images/image3.jpg"; width: 300; height: 200}',
                        container, "dynamicSnippet1");
                    newObject.x = 0;
                    newObject.y = root.position;
                }

            }

        }

        Component.onCompleted: {
            ImageCreator.createImageObject(0, 0);
            root.position += 200
        }
    }
}


在上面的代码中:

   Button {
                text: "Create New"

                onClicked: {
                    ImageCreator.createImageObject(0, root.position);
                    root.position += 200;
                }
            }

这个代码被用来生产我们所需要的QML Object, 并放置于我们所需要的位置。就像我们上一节中所介绍的那样,我们定义了一个“container”。这里实际上是一个Column的布局管理器。

另外,我们也可以使用代码:

           Button {
                text: "Create from string"

                onClicked: {
                   var newObject = Qt.createQmlObject('import QtQuick 2.0;
                        Image {source: "images/image3.jpg"; width: 300; height: 200}',
                        container, "dynamicSnippet1");
                    newObject.x = 0;
                    newObject.y = root.position;
                }

            }

使用字符串的方式 ,使用Qt.createQmlObject来创建我们的QML object。这也是一种简洁的方式。

运行我们的应用:





我们可以利用屏幕下面的按钮来动态生产我们的QML object。


4)动态生产QML Object的管理


我们可以通过使用destroy来销毁已经生产的QML object。为了管理我们的object,我们来创建一个ListModel:

        ListModel {
            id: objectsModel
        }

我们可以通过如下的方式来添加我们生成的object:

 function itemAdded(obj, source) {
        objectsModel.append({"obj": obj, "source": source})
    }

这样,每当我们创建一个新的object时,我们也把它添加进来:

       Row {
            anchors.bottom: parent.bottom
            anchors.horizontalCenter: parent.horizontalCenter
            anchors.bottomMargin: units.gu(1)
            spacing: units.gu(1)

            Button {
                text: "Create New"

                onClicked: {
                    var image = ImageCreator.createImageObject(0, root.position);
                    itemAdded(image, "dynamic-image.qml");
                    root.position += 200;
                }
            }

最后,我们可以通过如下的方式来销毁我们所创建的所有的dynamic-image.qml的object。

            Button {
                text: "Clear objects"

                onClicked: {
                    while(objectsModel.count > 0) {
                        objectsModel.get(0).obj.destroy();
                        objectsModel.remove(0);
                    }
                }
            }

   


上面右图是按下“Clear objects”后的显示。


整个项目的源码在: https://github.com/liu-xiao-guo/dynamicqml

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值