在这篇文章里,我们将学习如何使用QML的Qt.createComponent来动态生成我们所需要的Component。这是一个有趣的练习。我希望大家能跟随我一步一步地完成这个练习。最终使得大家对QML应用有更多的认识。这篇文章中我们也将使用我们的sensor来完成我们其中的一部分功能。在练习之前请大家先去按照安装Ubuntu SDK来安装好我们的环境。
1)使用Qt Creator创建一个最基本的应用
我们首先选择一个“App with Simple UI"的模版来创建我们的最基本的应用。在创建应用的时候,由于应用的package名字中不能出现大写的字母,所以我们选择使用小写的“
balloon"来作为我们的工程的名字:
紧接着,我们填入所需要的信息来完成我们的应用。
把应用的大小设为如下的值:
width: units.gu(50)
height: units.gu(75)
运行我们的应用:
我们看到,这个应用没有什么太多的内容。我们可以尝试点击按钮,然后看见方框中的文字发生改变。
2)添加Balloon Component
我们按照如下的图,用右键点击项目"balloon",并选择“
Add New"。
我们选择创建一个叫做“Balloon.qml”的文件。记住第一个字母为大写的字母。
至此我们已经创建了一个名字叫做"Balloon.qml"的component,虽然现在它做不了什么。为了测试我们刚刚已经创建好的Balloon Component,我们把我们的Balloon在main.qml中创建出来。现在我们来修改main.qml文件:
import QtQuick 2.0
import Ubuntu.Components 1.1
import "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.balloon"
//automaticOrientation: true
// Removes the old toolbar and enables new features of the new header.
useDeprecatedToolbar: false
width: units.gu(50)
height: units.gu(75)
Page {
title: i18n.tr("Balloon")
Balloon {
width: parent.width/3
height: parent.height/3
x: (parent.width - width) / 2
y: (parent.height - height) /2
}
}
}
这里我们把Balloon放到了我们主界面的正中央的位置。重新运行我们的程序,我们可以看到:
显然,我们可以看到,我们的Balloon component里没有任何的东西。只是一个白色方框在那里。但是,至少,我们可以看到确实Balloon已经能被正确地调用。在下面的章节中,我们来一步一步地完成我们的Balloon的功能。
3)完成Balloon模块
请到地址
https://github.com/liu-xiao-guo/balloon下载应用,并拷贝应用的"images"目录到我们已经创建好的项目中(别的文件不要拷贝)。这样使得我们的应用有一个叫做"images"的目录,里面有我们想要的图片。
打开我们的Balloon.qml文件。我们知道Balloon component其实是一个Image的item。我们首先把它设计为如下:
import QtQuick 2.0
Image {
id: balloon
width: 100
height: 250
source: "images/red.svg"
}
我们运行程序,我们发现它的结果如下:
显然,我们已经看到了我们所需要看到的气球了。只是它的颜色是固定的红色。我们想显示不同的气球。这时我们需要加入一个颜色的属性。我们的Balloon.qml的代码如下:
Image {
id: balloon
width: 100
height: 250
property string color: "red"
source: "images/" + color + ".svg"
}
默认的颜色我红色(在没有定义的情况下)。我们可以尝试改变我们的main.qml文件。加入color属性:
Balloon {
color: "green"
width: parent.width/3
height: parent.height/3
x: (parent.width - width) / 2
y: (parent.height - height) /2
}
再重新运行应用:
我们看见了一个绿色的气球。显然它的颜色属性是起作用的。为了能够使我们拖动鼠标移动气球,我们可以在Balloon.qml的Image中加入如下的代码:
MouseArea {
x: 0; y: parent.height/2
width: parent.width
height: parent.height/2
drag.target: parent
drag.axis: "XandYAxis"
}
再重新运行应用。我们尝试用鼠标点击气球的下半部,并移动气球。我们可以看到气球随着鼠标的移动而移动。下面,我们想在点击气球的上半部分时,气球发生爆炸。为了这样做,我们必须定义另外一个MouseArea来扑捉这个事件。当我们点击气球的上半部时会发出一个爆破声。
MouseArea {
x: 0; y: 0
width: parent.width
height: parent.height/2
onClicked: {
balloon.state = "exploded";
player.play();
}
}
为了我们能够听到一个声音,我们也同时定义了一个MediaPlayer。同时记得把刚下载好的程序中的"sounds"目录考到我们的项目中,并处于和“images”相同的目录中。
import QtMultimedia 5.0
Image {
...
MediaPlayer {
id: player
source: "sounds/blast.wav"
}
...
}
为了能够使得我们的应用能够在手机上播放出声音,我们必须为它加入我们所需要的security policy。为此,我们必须修改项目的“balloon.apparmor”文件:
有了“Audio”的policy,我们就可以在我们的手机上听到一声“砰”的声音(在气球爆炸的时候)。
states: [
State {
name: "exploded"
StateChangeScript {
script: {
// particle.running = true;
}
}
PropertyChanges {
target: balloon
visible: false
source: "images/" + color + "_exploded.png"
}
PropertyChanges {
target: balloon
opacity: 0
}
PropertyChanges {
target: balloon
scale: 0
}
// StateChangeScript { script: balloon.destroy(1000); }
}
]
这时我们重新运行我们的应用,我们会发现我们可以点击球的上半部,并听到一声爆破声。随后球就消失了。我们的目的达到了,但是,还不是我们最终想要的。这是因为从气球点击到消失,速度太快了。我们机会没有看到任何的中间过程。为了我们能够看到气球是怎么爆炸的,我们必须使用一个叫做 transition的。
transitions: [
Transition {
to: "exploded"
SequentialAnimation {
// Disappear
NumberAnimation { target: balloon; property: "opacity"
to: 0; duration: 800 }
NumberAnimation { target: balloon; property: "scale"
to: 0; duration: 800 }
PropertyAction { target: balloon; property: "source"
value: {
if ( !surprise )
"images/" + color + "_exploded.png"
else
"images/flower.png";
}
}
NumberAnimation { target: balloon; property: "opacity"
to: 1; duration: 300 }
NumberAnimation { target: balloon; property: "scale"
to: 1; duration: 300 }
PauseAnimation {
duration: {
if (surprise)
2000
else
800
}
}
PropertyAction { target: balloon; property: "visible"
value: "false"}
}
}
]
有了这个我们可以看到气球是逐渐消失的。我们在Image中也加入了如下的属性。当这个气球是一个surprise时,我们会显示一朵花:
Image {
id: balloon
width: 100
height: 250
property string color: "red"
property bool surprise: true
....
}
为了达到更加逼真的效果,我也为我们的Balloon加入了一个烟花的效果:
import QtQuick.Particles 2.0
...
Image {
...
ParticleSystem {
id: particle
anchors.fill: parent
running: false
Emitter {
group: "stars"
emitRate: 800
lifeSpan: 2400
size: 24
sizeVariation: 8
anchors.fill: parent
}
ImageParticle {
anchors.fill: parent
source: "qrc:///particleresources/star.png"
alpha: 0
alphaVariation: 0.2
colorVariation: 1.0
}
Emitter {
anchors.centerIn: parent
emitRate: 400
lifeSpan: 2400
size: 20 // 48
sizeVariation: 8
velocity: AngleDirection {angleVariation: 180; magnitude: 60}
}
Turbulence {
anchors.fill: parent
strength: 2
}
}
...
}
并在state变化时让它运行:
StateChangeScript {
script: {
particle.running = true;
}
}
运行应用,效果图如下:
至此所有的源码可以在如下的网址下载:
bzr branch
lp:~liu-xiao-guo/debiantrial/balloon1
由于篇幅的原因。我们将在下一篇文章中详细介绍怎么动态创建很多个Balloon的。大家敬请期待!