在这篇文章中介绍如何使用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;
}
}
另外,我们也可以使用代码:
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”后的显示。