目的:学习创建QML项目
参考blog:https://blog.csdn.net/encesu/article/details/95309010.
(QT开发版本:QT5.5.1)
步骤1:文件->新建文件或项目->其它项目->QT Quick Ui
生成*.qmlproject和*.qml两个文件,运行效果如下
按文章QmlBook-In-Chinese.pdf学习整理
从QML元素的层次结构来理解是最简单的学习方式。子元素从父元素上继承了坐标系统,它的x,y坐标总是相对应于它的父元素坐标系统。
利用简单的QML文件例子解释语法
import QtQuick 2.0
Rectangle {
//name this element
id:root
//properties::
width: 120; height: 280
//color property
color: "#D8D8D8"
//declare a nested element (child of root)
Image{
id:rocket
//reference the parent
x:(parent.width-width)/2;y:(parent.height-height)/2
source:'assets/rocket.png'
}
//Another child of root
Text{
//un-name element
//reference element by id
y:rocket.y+rocket.height+10
//reference root element
width: root.width
horizontalAlignment: Text.AlignHCenter
text:'rocket'
}
//Actions
MouseArea{
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
归纳如下:
1.import声明导入了一个指定的模块版本。一般来说会导入QtQuick2.0来作为初 始元素的引用。
2.每一个QML文件都需要一个根元素,就像HTML一样,根元素id通常可以命名为root(id:root)。
3.一个元素使用它的类型声明,然后使用{}进行包含。
4.元素拥有属性,他们按照name:value的格式来赋值。
5.任何在QML文档中的元素都可以使用它们的id进行访问(id是一个任意的标识 符)
6.元素可以嵌套,这意味着一个父元素可以拥有多个子元素。子元素可以通过访问parent关键字来访问它们的父元素。
元素使用他们的元素类型名进行声明,使用它们的属性或者创建自定义属性来定义。一个属性对应一个值,例如 width:100,text: ‘Greeting’, color: ‘#FF0000’。一 个属性有一个类型定义并且需要一个初始值。
import QtQuick 2.0
Rectangle{
width:120;height:240
Text {
//(1) identifier
id:thisLabel
//(2) set x- and y- Position
x:24;y:16
//(3) bind weight to 2*width
height:0.5*width
//(4) custom property
property int times:24
//(5) property alias
property alias anotherTimes:thisLabel.times
//(6) set text appended by value
text:"Greetings"+times
//(7) font is a grouped property
font.family: "Ubuntu"
font.pixelSize: 24
//(8) KeyNavigation is an attached property
KeyNavigation.tab: otherLabel
//(9) signal handle for property changes
onHeightChanged: console.log('height:',height)
//focus is needed to receive key events
focus:true
//change color based on focus value
color:focus?"red":"black"
}
Text{
//(1) identifier
id:otherLabel
x:24;y:64
font.family: "Ubuntu"
font.pixelSize: 24
text:'fight!!!'
//(4) focus is needed to receive key events
focus:true
//change color based on focus value
KeyNavigation.tab: thisLabel
color: focus?"red":"black"
}
}
归纳如下:
1.利用修饰符"property"可以添加自定义属性(格式:“property 类型 标识符:初始值”)
2.通过修饰符alias,属性别名添加属性(格式:“property alias 标识符:某一属性”)。alias关 键字允许我们转发一个属性或者转发一个属性对象自身到另一个作用域。我们 将在后面定义组件导出内部属性或者引用根级元素id会使用到这个技术。一个 属性别名不需要类型,它使用引用的属性类型或者对象类型。
3.属性绑定:一个属性可以依赖一个或 多个其它属性
4.一些属性是按组分配的属性。当一个属性需要结构化并且相关的属性需要联系 在一起时,我们可以这样使用它。另一个组属性的编码方式是 font{family: “UBuntu”; pixelSize: 24 }。
5.一些属性是元素自身的附加属性。这样做是为了全局的相关元素在应用程序中 只出现一次
6.对于每个元素你都可以提供一个信号操作。
QML与JavaScript关系
import QtQuick 2.0
Rectangle {
width:240;height:120
Text{
id:label
x:24;y:24
//custom counter property for space presses
property int spacePressed:0
text:'space key pressed times:'+spacePressed
//handle for text changed
onTextChanged:console.log("text change to:"+text)
//focus is needed to receive key events
focus:true
//handle with some js
Keys.onSpacePressed:{
increment()
}
function increment(){
spacePressed+=1
}
//function escape
Keys.onEscapePressed: {
label.text='0'
}
}
}
归纳如下:
QML的:(属性绑定)与JavaScript的=(赋值)是不同的。绑定是一个协议,并 且存在于整个生命周期。然而JavaScript赋值(=)只会产生一次效果。当一个新 的绑定生效或者使用JavaScript赋值给属性时,绑定的生命周期就会结束。例如一 个按键的操作设置文本属性为一个空的字符串将会销毁我们的增值显示:
元素可分为可视化元素与非可视化元素。可视化元素(如矩形框Rectangle)有着几何形状并可以在屏幕上显示;非可视化元素(例如计时器Timer)提供了常用的功能,通常用于操作非可视化元素。
本节专注于几个基础的可视化元素
Item(基础元素对象)是所有可视化元素的基础对象,所有其它的可视化元素都继承自Item。它自身不会有任何绘制操作,但是定义了所有可视化元素共有的属性:
anchors(锚定),包括左(left),右(right),上 (top),下(bottom),水平与垂直居中(vertical center,horizontal center),与margins(间距)一起 定义了元素与其它元素之间的位置关系。(在之后“布局元素”一节详细介绍)
附加属性key(按键)和keyNavigation(按键定位)属 性来控制按键操作,处理输入焦点(focus)可用操作。
缩放(scale)旋转(rotate)转换,通用的x,y,z 属性列表转换(transform),旋转基点设置(transformOrign)
1.opacity(不透明度)控制透明度
2.visible控制元素是否显示
3.clip(裁剪)用来限制元素边界的绘制
4.smooth(平滑)用来提高渲染质量
states(状态列表属性)提供了元素当前所支持的状态 列表,当前属性的改变也可以使用transitions(转变)属 性列表来定义状态转变动画
Item(基本元素对象)通常被用来作为其它元素的容器使用。
Rectangle(矩形框)是基本元素对象的一个扩展
1.增加了一个颜色来填充它(color)
2.支持边界的定义,使用border.color(边界颜色),border.width(边界宽度)来 自定义边界
3.radius(半径)属性来创建一个圆角矩形
import QtQuick 2.0
Item{
width:200
height:120
Rectangle{
id:rect1
x:12;y:12
width:76;height:96
color:'lightsteelblue'
}
Rectangle{
id:rect2
x:rect1.x+rect1.width+10;y:12
width:76;height:96
border.width: 4
border.color: 'lightsteelblue'
radius: 8
}
}
颜色的命名是来自SVG颜色的名称(查看http://www.w3.org/TR/css3-color/#svg-color.可以获取更多的颜色名称)。你也可以使用其它的方法来指定颜 色,比如RGB字符串(’#FF4444’),或者一个颜色名字(例如’white’)
此外,填充的颜色与矩形的边框也支持自定义的渐变色
Rectangle{
id:rect3;
x:rect2.x+rect2.width+10;y:12
width:76;height:96
color: "#104b51"
gradient: Gradient {
GradientStop {
position: 0.00;
color: "#104b51";
}
GradientStop {
position: 1.00;
color: "#ffffff";
}
}
一个渐变色是由一系列的梯度值定义的。每一个值定义了一个位置与颜色。位置标 记了y轴上的位置(0 = 顶,1 = 底)。GradientStop(倾斜点)的颜色标记了颜色 的位置。
这个函数无法创建一个梯形,最好使用一个已有的图像来创建梯形。
使用Text元素(Text Element)显示文本。可以使用字体属性组(font property group)来改变当前字体,例如font.family ,font.pixelSize等等
import QtQuick 2.0
Rectangle {
width:240;
height:240
Text{
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text:'Nice Weather'
color:'lightsteelblue'
font.family: 'Ubuntu'
font.pixelSize: 28
}
}
文本可以使用horizontalAlignment与verticalAlignment属性来设置它的对齐效果。为了提高文本的渲染效果,可以使用style和styleColor属性来配置文字的外框效果,浮雕效果或者凹陷效果。对于过长的文本,可能需要使用省略号来表示,例如Avery…longtext,可以使用elide属性来完成这个操作。elide属性允许你设置文本左边,右边或者中间的省略位置。如果不想’…'省略号出现,并且希望使用文字换行的方式显示所有的文本,可以使用wrapMode属性(这个属性只在明确设置了宽度后才生效):
import QtQuick 2.0
Rectangle {
width:400
height:200
Text{
width:80
height:120
text:'a very long text11111111'
//elide:Text.ElideMiddle
style:Text.Sunken
styleColor: '#FF4444'
font.family: 'Ubuntu'
font.italic: true
font.pixelSize: 24
wrapMode: Text.WordWrap
}
}
通常你想要对文本元素布局时,你需要区分文本在文本元素内部的边界对齐和由元素边界自动对齐。前一种情况你需要使用horizontalAlignment和verticalAlignment属性来完成,后一种情况你需要操作元素的几何形状或者使用anchors(锚定)来完成。
一个图像元素(ImageElement)能够显示不同格式的图像(例如PNG,JPG,GIF,BMP)。source属性(sourceproperty)提供了图像文件的链接信息,fillMode(文件模式)属性能够控制元素对象的大小调整行为。
Image {
x: 12; y: 12
// width: 72
// height: 72
source: "assets/triangle_red.png"
}
Image {
x: 12+64+12; y: 12
// width: 72
height: 72/2
source: "assets/triangle_red.png"
fillMode: Image.PreserveAspectCrop
clip: true
}
注意
一个URL可以是使用’/'语法的本地路径("./images/home.png")或者一个网络链接(“http://example.org/home.png”)。
注意
图像元素(Image element)使用PreserveAspectCrop可以避免裁剪图像数据被渲染到图像边界外。默认情况下裁剪是被禁用的(clip:false)。需要打开裁剪(clip:true)来约束边界矩形的绘制。这对任何可视化元素都是有效的。
建议
使用QQmlImageProvider可以通过C++代码来创建自己的图像提供器,这允许动态创建图像并且使用线程加载。
为了与不同的元素交互,通常需要使用MouseArea(鼠标区域)元素。这是一个矩形的非可视化元素对象,你可以通过它来捕捉鼠标事件。当用户与可视化端口交互时,mouseArea通常被用来与可视化元素对象一起执行命令。
Rectangle{
id:rect1
x:12;y:12
width:76;height:96
color:'lightsteelblue'
MouseArea{
id:area
width:parent.width
height:parent.height
onClicked: rect2.visible=!rect2.visible
}
}
Rectangle{
id:rect2
x:rect1.x+rect1.width+10;y:12
width:76;height:96
border.width: 4
border.color: 'lightsteelblue'
radius: 8
}
组件是一个可以重复使用的元素,QML提供几种不同的方法来创建组件。但是目前我们只对其中一种方法进行讲解:一个文件就是一个基础组件。一个以文件为基础的组件在文件中创建了一个QML元素,并且将文件以元素类型来命名(例如Button.qml)。你可以像任何其它的QtQuick模块中使用元素一样来使用这个组件。在我们下面的例子中,你将会使用你的代码作为一个Button(按钮)来使用。
注意
文件名首字母需要大写
//MyButton.qml
import QtQuick 2.5
Rectangle {
id:root
//只有根目录下的元素才能被输出
signal beclicked
property alias text2:label.text
width:116;height:26
color:'lightsteelblue'
border.color:'slategray'
Text{
id:label
anchors.centerIn: parent //将子控件放置在父控件中心
text:'Start'
}
MouseArea{
anchors.fill: parent //将子控件大小和方位设置与父控件相同,即覆盖
onClicked: {
root.beclicked()
}
}
}
我们在根级导出了文本和点击信号。通常我们命名根元素为root让引用更加方便。我们使用了QML的alias(别名)的功能,它可以将内部嵌套的QML元素的属性导出到外面使用。有一点很重要,只有根级目录的属性才能够被其它文件的组件访问。
//reusable_component.qml
import QtQuick 2.5
Rectangle {
width:140
height:120
MyButton{
id:button
x:12;y:12
text2:'Click me'
onBeclicked: {
status.text='Button clicked'
}
}
Text{
id:status
anchors.top: button.bottom
anchors.topMargin: 10
anchors.left: button.left
horizontalAlignment: Text.AlignHCenter //字体对齐方式为中心对齐
width:116;height:26
text:'waiting...'
}
}
QML元素对象通常能够被平移,旋转,缩 放。
简单的位移是通过改变x,y坐标来完成的。旋转是改变rotation(旋转)属性来完成的,这个值使用角度作为单位(0~360)。缩放是通过改变scale(比例)的属性来完成的,小于1意味着缩小,大于1意味着放大。旋转与缩放不会改变对象的几何形状,对象的x,y(坐标)与width/height(宽/高)也类似。只有绘制指令是被转换的对象。
以下第一个文件为包含鼠标区域的图像元素
第二个文件是对3个图像元素平移,旋转,缩 放示例
antializing:true 为抗锯齿属性,常用于缩放图片
//ClickableImage.qml
import QtQuick 2.0
Image {
id:root
signal beclicked
MouseArea{
anchors.fill: parent
onClicked: root.beclicked()
}
}
//transformation.qml
import QtQuick 2.0
Rectangle {
id:root
width:background.width
height:background.height
Image{
id:background
source:'asserts/background.png'
MouseArea{
anchors.fill: parent
onClicked: {
image1.x=20
image2.rotation=0
image3.rotation=0
image3.scale=1.0
}
}
}
ClickableImage{
id:image1
x:20;y:100
source: 'asserts/circle_blue.png'
smooth: true
onBeclicked: {
x+=10
}
}
ClickableImage{
id:image2
x:160;y:100
source:'asserts/[email protected]'
antialiasing: true
onBeclicked: {
image2.rotation+=25
}
}
ClickableImage{
id:image3
x:260;y:100
source:'asserts/triangle_red.png'
antialiasing:true
onBeclicked: {
image3.rotation+=25
image3.scale+=0.05
}
}
}
有一些QML元素被用于放置元素对象,它们被称作定位器,QtQuick模块提供了Row,Column,Grid,Flow用来作为定位器。
注意
首先介绍一些基本元素,红色(red),蓝色(blue),绿色(green),高亮(lighter)与黑暗(darker)方块,每一个组件都包含了一个48乘48的着色区域。下面是关于RedSquare(红色方块)的代码:
//RedSquare.qml
import QtQuick 2.0
Rectangle {
width:48;height:48
color:'#ea7025'
border.color: Qt.lighter(color)
}
Column(列)元素将它的子对象通过顶部对齐的列方式进行排列。spacing属性用来设置每个元素之间的间隔大小。
import QtQuick 2.0
Rectangle {
width:100
height:160
Column{
id:mycolumn
anchors.fill:parent
spacing: 5
BlueSquare{}
BrighterSquare{}
RedSquare{width:100}
}
}
Row(行)元素将它的子对象从左到右,或者从右到左依次排列,排列方式取决于layoutDirection属性。spacing属性用来设置每个元素之间的间隔大小。
import QtQuick 2.0
Rectangle {
width:300
height:50
Row{
id:myRow
anchors.fill:parent
spacing: 5
BlueSquare{}
BrighterSquare{}
RedSquare{width:100}
layoutDirection: Qt.RightToLeft//默认为Qt.LeftToRight
}
}
Grid(栅格)元素通过设置rows(行数)和columns(列数)将子对象排列在一个栅格中。可以只限制行数或者列数。如果没有设置它们中的任意一个,栅格元素会自动计算子项目总数来获得配置,例如,设置rows(行数)为3,添加了6个子项目到元素中,那么会自动计算columns(列数)为2。属性flow(流)与layoutDirection(布局方向)用来控制子元素的加入顺序。spacing属性用来控制所有元素之间的间隔。
import QtQuick 2.0
BrighterSquare {
width:160
height:160
Grid{
rows:2
columns:2
spacing: 10
anchors.centerIn: parent
BlueSquare{}
DarkerSquare{}
Item{width:48;height:48}
GreenSquare{}
//RedSquare{}
}
}
最后一个定位器是Flow(流)。通过flow(流)属性和layoutDirection(布局方向)属性来控制流的方向。它能够从头到底的横向布局,也可以从左到右或者从右到左进行布局。作为加入流中的子对象,它们在需要时可以被包装成新的行或者列。为了让一个流可以工作,必须指定一个宽度或者高度,可以通过属性直接设定,或者通过anchor(锚定)布局设置。
import QtQuick 2.0
BrighterSquare {
width:200
height:200
Flow{
anchors.fill:parent
anchors.margins: 20
spacing: 20
BlueSquare{}
DarkerSquare{}
RedSquare{}
}
}
通常Repeater(重复元素)与定位器一起使用。它的工作方式就像for循环与迭代器的模式一样。
import QtQuick 2.5
DarkSquare {
id: root
width: 252
height: 252
property variant colorArray: ["#00bde3", "#67c111", "#ea7025"]
Grid{
anchors.fill: parent
anchors.margins: 8
spacing: 4
Repeater {
model: 16
Rectangle {
width: 56; height: 56
property int colorIndex: Math.floor(Math.random()*3)
color: root.colorArray[colorIndex]
border.color: Qt.lighter(color)
Text {
anchors.centerIn: parent
color: "#f0f0f0"
text: "Cell " + index
}
}
}
}
}
QML使用anchors(锚)对元素进行布局。anchoring(锚定)是基础元素对象的基本属性,可以被所有的可视化QML元素使用。一个anchors(锚)就像一个协议,并且比几何变化更加强大。Anchors(锚)是相对关系的表达式,你通常需要与其它元素搭配使用。
一个元素有6条锚定线(top顶,bottom底,left左,right右,horizontalCenter水平中,verticalCenter垂直中)。在文本元素(TextElement)中有一条文本的锚定基线(baseline)。
每一条锚定线都有一个偏移(offset)值,在top(顶),bottom(底),left(左),right(右)的锚定线中它们也被称作边距。
对于horizontalCenter(水平中)与verticalCenter(垂直中)与baseline(文本基线)中被称作偏移值。
1.元素填充父元素
GreenSquare{
RedSquare{
anchors.fill: parent//填充
anchors.margins: 8//设置边距,不设置默认值为0,完全覆盖
text:'(1)'
}
}
2.元素左对齐它的父元素
GreenSquare{
RedSquare{
width:1/2*parent.width
anchors.left: parent.left
anchors.leftMargin: 8
text:'(2)'
}
}
3.元素的左边与父元素的右边对齐
GreenSquare{
RedSquare{
width:1/2*parent.width
anchors.left: parent.right
//anchors.leftMargin: 8
text:'(3)'
}
}
4.元素1与父元素水平中心对齐,元素2与元素1水平中心对齐,元素2顶端与元素1底端对齐
GreenSquare{
RedSquare{
id:redSquare1
y:8
width:48;height:24
anchors.horizontalCenter: parent.horizontalCenter
}
RedSquare{
width:24
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: redSquare1.bottom
anchors.topMargin: 8
text:'(4)'
}
}
5.元素在它的父元素中居中
GreenSquare{
RedSquare{
width:1/2*parent.width
anchors.centerIn: parent
//anchors.leftMargin: 8
text:'(5)'
}
}
6.元素水平方向居中对齐父元素并向后偏移12像素,垂直方向居中对齐。
GreenSquare{
RedSquare{
width:1/2*parent.width
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: 12
anchors.verticalCenter: parent.verticalCenter
text:’(6)’
}
}
注意:
当所有方格MouseArea中打开了拖拽功能时(drag.target: parent),方格(2)(3)(4)可以上下移动,因为它们只有左边被固定住了,拖拽一个元素意味着会改变它的x,y坐标。anchoring(锚定)比几何变化(例如x,y坐标变化)更强大是因为锚定线(anchoredlines)的限制,我们将在后面讨论动画时看到这些功能的强大。
文本输入允许用户输入一行文本。这个元素支持使用正则表达式验证器来限制输入和输入掩码的模式设置。
import QtQuick 2.0
Rectangle {
id:root
width:200;
height:80
TextInput{
id:input1
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top;
anchors.topMargin: 10
width:150
height:30
focus:true
text:'Input1'
font.family: 'Times New Roman'
font.pixelSize: 20
KeyNavigation.tab: input2
}
TextInput{
id:input2
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: input1.bottom
anchors.topMargin: 10
width:150
height:30
text:'Input2'
font.family: 'Times New Roman'
font.pixelSize: 20
KeyNavigation.tab: input1
onFocusChanged: console.log('focuschanged')
}
}
用户可以通过点击TextInput来改变焦点。为了支持键盘改变焦点,我们可以使用 KeyNavigation(按键向导)这个附加属性。
用户需要一些可见的修饰来鉴别这是一个输入元素,例如一个简单的矩形框。当你放置一个TextInput(文本输入)在一个元素中时,你需要确保其它的元素能够访问它导出的大多数属性。我们提取这一段代码作为我们自己的组件,称作TLineEditV1用来重复使用
import QtQuick 2.0
Rectangle {
width:96;height:30
color:'lightsteelblue'
border.color: Qt.lighter(color)
property alias text:input.text
property alias input:input
TextInput{
id:input
anchors.fill:parent
anchors.margins: 4
focus:true
font.family: 'Times New Roman'
font.pixelSize: 20
}
}
import QtQuick 2.0
Rectangle {
id:root
width:200;
height:80
TLineEditV1{
id:input1
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top;
anchors.topMargin: 10
width:150
height:30
text:'Input1'
KeyNavigation.tab: input2
}
TLineEditV1{
id:input2
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: input1.bottom
anchors.topMargin: 10
width:150
height:30
text:'Input2'
KeyNavigation.tab: input1
}
}
尝试使用Tab按键来导航,会发现焦点无法切换到input2上。这个例子中使用focus:true的方法不正确,这个问题是因为焦点被转移到input2元素时,包含TlineEditV1的顶部元素接收了这个焦点并且没有将焦点转发给TextInput(文本输入)。为了防止这个问题,QML提供了FocusScope(焦点区域)。
一个焦点区域(focusscope)定义了如果焦点区域接收到焦点,它的最后一个使用focus:true的子元素接收焦点,它将会把焦点传递给最后申请焦点的子元素。我们创建了第二个版本的TLineEdit组件,称作TLineEditV2,使用焦点区域(focusscope)作为根元素。
import QtQuick 2.0
FocusScope{
width:96;height:30
property alias text:input.text
property alias input:input
Rectangle{
anchors.fill: parent
color:'lightsteelblue'
border.color: Qt.lighter(color)
}
TextInput{
id:input
anchors.fill:parent
anchors.margins: 4
focus:true
font.family: 'Times New Roman'
font.pixelSize: 20
}
}
利用TLineEditV2重写按键导航
import QtQuick 2.0
Rectangle {
id:root
width:200;
height:80
TLineEditV2{
id:input1
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top;
anchors.topMargin: 10
width:150
height:30
focus:true
text:'Input1'
KeyNavigation.tab: input2
}
TLineEditV2{
id:input2
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: input1.bottom
anchors.topMargin: 10
width:150
height:30
text:'Input2'
KeyNavigation.tab: input1
}
}
可以正常切换
文本编辑(TextEdit)元素与文本输入(TextInput)非常类似,它支持多行文本编辑。它不再支持文本输入的限制,但是提供了已绘制文本的大小查询(paintedHeight,paintedWidth)。我们也创建了一个我们自己的组件TTextEdit,可以编辑它的背景,使用focusscope(焦点区域)来更好的切换焦点。
import QtQuick 2.0
FocusScope{
width:96;height:input.height+30
property alias text:input.text
property alias input:input
Rectangle{
anchors.fill: parent
color:'lightsteelblue'
border.color: Qt.lighter(color)
}
TextEdit{
id:input
anchors.fill:parent
anchors.margins: 4
focus:true
font.family: 'Times New Roman'
font.pixelSize: 20
}
}
附加属性key允许你基于某个按键的点击来执行代码。例如使用up,down按键来移动一个方块,left,right按键来旋转一个元素,plus,minus按键来缩放一个元素。
import QtQuick 2.0
Rectangle {
width:400;height:200
color: "#3c3c3c"
border.color: Qt.darker(color)
Rectangle{
id:square
color:'red'
width:48;height:48
x:8;y:8
}
focus:true
Keys.onLeftPressed: square.x-=8
Keys.onRightPressed: square.x+=8
Keys.onUpPressed: square.y-=8
Keys.onDownPressed: square.y+=8
Keys.onPressed: {
switch(event.key){
case Qt.Key_Plus:
square.scale+=0.05;
break;
case Qt.Key_Minus:
square.scale-=0.05;
break;
}
}
}