目录
简单变换
变换操作可以改变对象的几何形态。通常情况下,QML 项目(Items)可以进行平移、旋转和缩放。这些操作既有简单形式,也有更高级的实现方式。
让我们从简单变换开始。以下是作为起点的场景。
简单的平移是通过改变 x,y 位置来实现的。旋转是通过 rotation 属性完成的,其值以度为单位(0 ... 360)。缩放是通过 scale 属性实现的,值小于 1 表示缩小,而>1则表示放大。旋转和缩放不会改变项目的几何属性:其 x,y 和 width/height 保持不变,改变的仅仅是绘图指令。
在展示示例之前,我想介绍一个小助手: ClickableImage 元素。 ClickableImage 只是一个带有鼠标区域(Mouse Area)的图像。这引出了一个非常有用的经验法则------如果你已经三次复制了同一段代码,请将其提取为一个组件。
// ClickableImage.qml
// Simple image which can be clicked
import QtQuick
Image {
id: root
signal clicked
MouseArea {
anchors.fill: parent
onClicked: root.clicked()
}
}

我们使用可点击图像来展示三个对象(方块、圆圈、三角形)。点击每个对象时,它都会执行一个简单的变换。点击背景则会重置场景。
// TransformationExample.qml
import QtQuick
Item {
// set width based on given background
width: bg.width
height: bg.height
Image { // nice background image
id: bg
source: "assets/background.png"
}
MouseArea {
id: backgroundClicker
// needs to be before the images as order matters
// otherwise this mousearea would be before the other elements
// and consume the mouse events
anchors.fill: parent
onClicked: {
// reset our little scene
circle.x = 84
box.rotation = 0
triangle.rotation = 0
triangle.scale = 1.0
}
}
ClickableImage {
id: circle
x: 84; y: 68
source: "assets/circle_blue.png"
antialiasing: true
onClicked: {
// increase the x-position on click
x += 20
}
}
ClickableImage {
id: box
x: 164; y: 68
source: "assets/box_green.png"
antialiasing: true
onClicked: {
// increase the rotation on click
rotation += 15
}
}
ClickableImage {
id: triangle
x: 248; y: 68
source: "assets/triangle_red.png"
antialiasing: true
onClicked: {
// several transformations
rotation += 15
scale += 0.05
}
}

圆圈在每次点击时会增加 x 轴坐标,方块在每次点击时会旋转。三角形在每次点击时会旋转并放大图像,以演示组合变换。对于缩放和旋转操作,我们设置了 antialiasing: true 来开启抗锯齿,出于性能考虑,该功能默认是关闭的(与裁剪属性 clip 相同)。在您自己的工作中,如果您发现图形中出现锯齿边缘,那么您可能应该开启平滑处理。
提示
为了在缩放图像时获得更好的视觉质量,建议缩小图像而不是放大。以较大的缩放系数放大图像会导致缩放伪影(图像模糊)。在缩放图像时,你应该考虑使用 smooth: true ,以性能为代价启用更高质量的过滤器。
背景 MouseArea 覆盖了整个背景并重置了对象值。
在代码中较早出现的元素具有较低的堆叠顺序(称为 z-order)。如果你点击 circle 足够长的时间,你会看到它移动到了 box 的下方。z-order 也可以通过 Item 的 z 属性进行操作。
这是因为 box 在代码中出现得较晚。这同样适用于鼠标区域(mouse areas)。在代码中较晚出现的鼠标区域会覆盖(并因此抓取鼠标事件)较早出现的鼠标区域。
请记住:文档中元素的顺序非常重要。