在这篇文章中介绍如何使用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。为了能够删除我们生产的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”后的显示。
整个项目的源码在: git clone https://gitcafe.com/ubuntu/dynamicqml.git
版权声明:本文为博主原创文章,未经博主允许不得转载。