我们知道在触屏的手机中,可以利用手势可以产生一下动作。特别是Ubuntu手机,手势的操作利用的非常多。那么怎么可以在QML应用中侦测到手势呢?我以前在我的Flickr应用使用到一个手势的侦测。今天我们利用网上的一个例程来,做一个例子。这个例程更加具有可以重复利用性。我们的参阅代码地址:https://gist.github.com/kovrov/1742405
SwipeArea.qml
/* This code was written by Sergejs Kovrovs and has been placed in the public domain. */ import QtQuick 2.0 MouseArea { property point origin property bool ready: false property int threshold: units.gu(20) signal move(int x, int y) signal swipe(string direction) onPressed: { drag.axis = Drag.XAndYAxis origin = Qt.point(mouse.x, mouse.y) } onPositionChanged: { switch (drag.axis) { case Drag.XAndYAxis: if (Math.abs(mouse.x - origin.x) > threshold ) { drag.axis = Drag.XAxis } else if (Math.abs(mouse.y - origin.y) > threshold) { drag.axis = Drag.YAxis } break case Drag.XAxis: move(mouse.x - origin.x, 0) break case Drag.YAxis: move(0, mouse.y - origin.y) break } } onReleased: { switch (drag.axis) { case Drag.XAndYAxis: canceled(mouse) break case Drag.XAxis: swipe(mouse.x - origin.x < 0 ? "left" : "right") break case Drag.YAxis: swipe(mouse.y - origin.y < 0 ? "up" : "down") break } } }
这里的代码定义了一个新的MouseArea的Component。这个Component可以在任何其它需要用到MouseArea的地方用到。你也可以理解为MouseArea的重载(从C++的角度,虽然并不精确)。我们对原作者的代码没有更多的改动,但是,我重新定义了一个“threshold”。这个是用来调整我们的Swipe的灵敏度的。比如,一个较大的值,使得我们必须使用较大的滑动才可以产生swipe的信号。较小的值,使得swipe的侦测更加容易。这个可以根据我们在实际的应用中进行调整。
那么我们如何使用这个SwipeArea的Component呢?
Swipe.qml
/* This code was written by Sergejs Kovrovs and has been placed in the public domain. */ import QtQuick 2.0 Item { id: root width: 480 height: 320 property var itemData: ["#22eeeeee", "#22bbbbbb", "#22888888", "#22555555", "#22222222"] property int currentIndex: 0 onCurrentIndexChanged: { slide_anim.to = - root.width * currentIndex slide_anim.start() } PropertyAnimation { id: slide_anim target: content easing.type: Easing.OutExpo properties: "x" } Image { id: img anchors.verticalCenter: root.verticalCenter source: "images/wallpaper.jpg" fillMode: Image.PreserveAspectCrop } Item { id: content width: root.width * itemData.length property double k: (content.width - root.width) / (img.width - root.width) onXChanged: { img.x = x / k // console.log("img.x: " + img.x ); } Repeater { model: itemData.length Rectangle { x: root.width * index width: root.width; height: root.height color: itemData[index] Text { text: index+1; anchors.centerIn: parent; font.pointSize: 100; color: "#88000000" } } } } SwipeArea { id: mouse anchors.fill: parent onMove: { content.x = (-root.width * currentIndex) + x // console.log("content.x " + content.x); } onSwipe: { switch (direction) { case "left": if (currentIndex === itemData.length - 1) { currentIndexChanged() } else { currentIndex++ } break case "right": if (currentIndex === 0) { currentIndexChanged() } else { currentIndex-- } break } } onCanceled: { currentIndexChanged() } } Row { anchors { bottom: parent.bottom; bottomMargin: 16; horizontalCenter: parent.horizontalCenter } spacing: 16 Repeater { model: itemData.length Rectangle { width: 12; height: 12; radius: 6 color: currentIndex === index ? "#88ffffff" : "#88000000" border { width: 2; color: currentIndex === index ? "#33000000" : "#11000000" } } } } }
就像我们正常情况下使用MouseArea的情况一样,我们可以在我们需要侦测滑动的地方使用SwipeArea。这样,我们只需要捕获SwipeArea中发出的信号:
SwipeArea { id: mouse anchors.fill: parent onMove: { content.x = (-root.width * currentIndex) + x // console.log("content.x " + content.x); } onSwipe: { switch (direction) { case "left": if (currentIndex === itemData.length - 1) { currentIndexChanged() } else { currentIndex++ } break case "right": if (currentIndex === 0) { currentIndexChanged() } else { currentIndex-- } break } } onCanceled: { currentIndexChanged() } }
这里,我们可以捕获onSwipe就可以得到Swipe的方向。在本例子中,我们只对左右感兴趣。我们可以通过手势向左或向右滑动来看一个图片的其它的部分。
整个测试项目的源码在:git clone https://gitcafe.com/ubuntu/swipe.git
时间: 2024-10-31 10:17:56