如何在 Qt 4.8 中创建滑动效果?
How to create a swipe effect in Qt 4.8?
我需要创建一个屏幕,用户可以在其中向右或向左、向上或向下滑动,并且在每个屏幕上我都会显示另一个屏幕。它就像一个十字,中心和两端是系统的另一个屏幕。
我尝试使用 GestureArea,但它唯一有效的事件是 onTapAndHold,其他事件如 onSwipe 则没有 运行。后来发现是Qt 4.8 GestureArea 有bug,其他事件不起作用。问题是单击时 onTapAndHold 事件 运行s,我只希望它与滑动事件一起 运行。
完成!
我是怎么做到的:
import QtQuick 1.1
import Qt.labs.gestures 1.0
import "module"
Rectangle {
id: recMainWindow
width: 800
height: 480
color: "#00000000"
property string strActualScreen: "screenCenter"
function funSwipeScreens(swipeArea)
{
if ((!panBottomCenter.running) && (!panCenterBottom.running) &&
(!panCenterLeft.running) && (!panCenterRight.running) &&
(!panCenterTop.running) && (!panLeftCenter.running) &&
(!panRightCenter.running) && (!panTopCenter.running))
{
if (swipeArea == "top")
{
if (strActualScreen == "screenBottom")
{
strActualScreen = "screenCenter";
marLeft.enabled = true;
marRight.enabled = true;
marBottom.enabled = true;
panBottomCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenTop";
marTop.enabled = false;
marLeft.enabled = false;
marRight.enabled = false;
panCenterTop.start();
}
}
else if (swipeArea == "bottom")
{
if (strActualScreen == "screenTop")
{
strActualScreen = "screenCenter";
marTop.enabled = true;
marLeft.enabled = true;
marRight.enabled = true;
panTopCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenBottom";
marLeft.enabled = false;
marRight.enabled = false;
marBottom.enabled = false;
panCenterBottom.start();
}
}
else if (swipeArea == "left")
{
if (strActualScreen == "screenRight")
{
strActualScreen = "screenCenter";
marBottom.enabled = true;
marRight.enabled = true;
marTop.enabled = true;
panRightCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenLeft";
marLeft.enabled = false;
marBottom.enabled = false;
marTop.enabled = false;
panCenterLeft.start();
}
}
else if (swipeArea == "right")
{
if (strActualScreen == "screenLeft")
{
strActualScreen = "screenCenter";
marLeft.enabled = true;
marBottom.enabled = true;
marTop.enabled = true;
panLeftCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenRight";
marBottom.enabled = false;
marRight.enabled = false;
marTop.enabled = false;
panCenterRight.start();
}
}
}
}
Loader {
id: loaCenter
x: 0
y: 0
source: "qrc:/qml/centerScreen"
}
Loader {
id: loaTop
x: 0
y: -480
source: "qrc:/qml/topScreen"
}
Loader {
id: loaBottom
x: 0
y: 480
source: "qrc:/qml/bottomScreen"
}
Loader {
id: loaLeft
x: -800
y: 0
source: "qrc:/qml/leftScreen"
}
Loader {
id: loaRight
x: 800
y: 0
source: "qrc:/qml/rightScreen"
}
GestureArea {
id: marLeft
x: 0
y: 100
width: 100
height: 280
focus: true
onTapAndHold: {
funSwipeScreens("left");
}
}
GestureArea {
id: marRight
x: 700
y: 100
width: 100
height: 280
focus: true
onTapAndHold: {
funSwipeScreens("right");
}
}
GestureArea {
id: marTop
x: 100
y: 0
width: 600
height: 100
focus: true
onTapAndHold: {
funSwipeScreens("top");
}
}
GestureArea {
id: marBottom
x: 100
y: 380
width: 600
height: 100
focus: true
onTapAndHold: {
funSwipeScreens("bottom");
}
}
// TOP ANIMATIONS
ParallelAnimation {
id: panCenterTop
NumberAnimation { target: loaCenter; property: "y"; from: 0; to: 480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaTop; property: "y"; from: -480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panTopCenter
NumberAnimation { target: loaTop; property: "y"; from: 0; to: -480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "y"; from: 480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// BOTTOM ANIMATIONS
ParallelAnimation {
id: panCenterBottom
NumberAnimation { target: loaCenter; property: "y"; from: 0; to: -480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaBottom; property: "y"; from: 480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panBottomCenter
NumberAnimation { target: loaBottom; property: "y"; from: 0; to: 480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "y"; from: -480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// LEFT ANIMATIONS
ParallelAnimation {
id: panCenterLeft
NumberAnimation { target: loaCenter; property: "x"; from: 0; to: 800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaLeft; property: "x"; from: -800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panLeftCenter
NumberAnimation { target: loaLeft; property: "x"; from: 0; to: -800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "x"; from: 800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// RIGHT ANIMATIONS
ParallelAnimation {
id: panCenterRight
NumberAnimation { target: loaCenter; property: "x"; from: 0; to: -800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaRight; property: "x"; from: 800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panRightCenter
NumberAnimation { target: loaRight; property: "x"; from: 0; to: 800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "x"; from: -800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
}
编辑:
好吧......在检查了我上面使用的 GestureArea 导致的错误行为之后,因为它们响应了 onTapAndHold 事件上的点击,而我只是想要滑动事件的答案,我决定删除它们并使用 MouseArea 进行滑动模拟. .
滑动操作有了很大改进,GestureArea 出现的点击事件问题已经解决,但导致了 MouseAreas 覆盖问题。
这在使用 GestureArea 时不存在,因为它不会阻止点击位于其下方的 MouseArea,而 MouseAreas overlap 会阻止点击。
总之GestureArea滑动事件的解决方法我在下面描述:
MouseArea {
anchors.fill: parent
preventStealing: true
property real reaSpeed: 0.0 // calculates drag speed for swipe to run
property int intStartY: 0 // starting point pressed by the user's finger
property bool booTracing: false //controls the analyzed drag length
onPressed: {
intStartY = mouse.y;
reaSpeed = 0;
booTracing = true;
}
onPositionChanged: {
if (!booTracing)
{
return;
}
reaSpeed = (intStartY - mouse.y) / 2.0;
if ((reaSpeed > 50) && (mouse.y < (parent.height * 0.2)))
{
booTracing = false;
if (booIsShowMenu)
{
sigStartHideMenu();
}
funSwipeScreens("bottom");
}
}
}
我正在检查一种处理 MouseAreas 覆盖的方法。
我需要创建一个屏幕,用户可以在其中向右或向左、向上或向下滑动,并且在每个屏幕上我都会显示另一个屏幕。它就像一个十字,中心和两端是系统的另一个屏幕。
我尝试使用 GestureArea,但它唯一有效的事件是 onTapAndHold,其他事件如 onSwipe 则没有 运行。后来发现是Qt 4.8 GestureArea 有bug,其他事件不起作用。问题是单击时 onTapAndHold 事件 运行s,我只希望它与滑动事件一起 运行。
完成!
我是怎么做到的:
import QtQuick 1.1
import Qt.labs.gestures 1.0
import "module"
Rectangle {
id: recMainWindow
width: 800
height: 480
color: "#00000000"
property string strActualScreen: "screenCenter"
function funSwipeScreens(swipeArea)
{
if ((!panBottomCenter.running) && (!panCenterBottom.running) &&
(!panCenterLeft.running) && (!panCenterRight.running) &&
(!panCenterTop.running) && (!panLeftCenter.running) &&
(!panRightCenter.running) && (!panTopCenter.running))
{
if (swipeArea == "top")
{
if (strActualScreen == "screenBottom")
{
strActualScreen = "screenCenter";
marLeft.enabled = true;
marRight.enabled = true;
marBottom.enabled = true;
panBottomCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenTop";
marTop.enabled = false;
marLeft.enabled = false;
marRight.enabled = false;
panCenterTop.start();
}
}
else if (swipeArea == "bottom")
{
if (strActualScreen == "screenTop")
{
strActualScreen = "screenCenter";
marTop.enabled = true;
marLeft.enabled = true;
marRight.enabled = true;
panTopCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenBottom";
marLeft.enabled = false;
marRight.enabled = false;
marBottom.enabled = false;
panCenterBottom.start();
}
}
else if (swipeArea == "left")
{
if (strActualScreen == "screenRight")
{
strActualScreen = "screenCenter";
marBottom.enabled = true;
marRight.enabled = true;
marTop.enabled = true;
panRightCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenLeft";
marLeft.enabled = false;
marBottom.enabled = false;
marTop.enabled = false;
panCenterLeft.start();
}
}
else if (swipeArea == "right")
{
if (strActualScreen == "screenLeft")
{
strActualScreen = "screenCenter";
marLeft.enabled = true;
marBottom.enabled = true;
marTop.enabled = true;
panLeftCenter.start();
}
else if (strActualScreen == "screenCenter")
{
strActualScreen = "screenRight";
marBottom.enabled = false;
marRight.enabled = false;
marTop.enabled = false;
panCenterRight.start();
}
}
}
}
Loader {
id: loaCenter
x: 0
y: 0
source: "qrc:/qml/centerScreen"
}
Loader {
id: loaTop
x: 0
y: -480
source: "qrc:/qml/topScreen"
}
Loader {
id: loaBottom
x: 0
y: 480
source: "qrc:/qml/bottomScreen"
}
Loader {
id: loaLeft
x: -800
y: 0
source: "qrc:/qml/leftScreen"
}
Loader {
id: loaRight
x: 800
y: 0
source: "qrc:/qml/rightScreen"
}
GestureArea {
id: marLeft
x: 0
y: 100
width: 100
height: 280
focus: true
onTapAndHold: {
funSwipeScreens("left");
}
}
GestureArea {
id: marRight
x: 700
y: 100
width: 100
height: 280
focus: true
onTapAndHold: {
funSwipeScreens("right");
}
}
GestureArea {
id: marTop
x: 100
y: 0
width: 600
height: 100
focus: true
onTapAndHold: {
funSwipeScreens("top");
}
}
GestureArea {
id: marBottom
x: 100
y: 380
width: 600
height: 100
focus: true
onTapAndHold: {
funSwipeScreens("bottom");
}
}
// TOP ANIMATIONS
ParallelAnimation {
id: panCenterTop
NumberAnimation { target: loaCenter; property: "y"; from: 0; to: 480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaTop; property: "y"; from: -480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panTopCenter
NumberAnimation { target: loaTop; property: "y"; from: 0; to: -480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "y"; from: 480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// BOTTOM ANIMATIONS
ParallelAnimation {
id: panCenterBottom
NumberAnimation { target: loaCenter; property: "y"; from: 0; to: -480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaBottom; property: "y"; from: 480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panBottomCenter
NumberAnimation { target: loaBottom; property: "y"; from: 0; to: 480; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "y"; from: -480; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// LEFT ANIMATIONS
ParallelAnimation {
id: panCenterLeft
NumberAnimation { target: loaCenter; property: "x"; from: 0; to: 800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaLeft; property: "x"; from: -800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panLeftCenter
NumberAnimation { target: loaLeft; property: "x"; from: 0; to: -800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "x"; from: 800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
// RIGHT ANIMATIONS
ParallelAnimation {
id: panCenterRight
NumberAnimation { target: loaCenter; property: "x"; from: 0; to: -800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaRight; property: "x"; from: 800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
ParallelAnimation {
id: panRightCenter
NumberAnimation { target: loaRight; property: "x"; from: 0; to: 800; duration: 250; easing.type: Easing.InOutQuad }
NumberAnimation { target: loaCenter; property: "x"; from: -800; to: 0; duration: 250; easing.type: Easing.InOutQuad }
}
}
编辑:
好吧......在检查了我上面使用的 GestureArea 导致的错误行为之后,因为它们响应了 onTapAndHold 事件上的点击,而我只是想要滑动事件的答案,我决定删除它们并使用 MouseArea 进行滑动模拟. .
滑动操作有了很大改进,GestureArea 出现的点击事件问题已经解决,但导致了 MouseAreas 覆盖问题。
这在使用 GestureArea 时不存在,因为它不会阻止点击位于其下方的 MouseArea,而 MouseAreas overlap 会阻止点击。
总之GestureArea滑动事件的解决方法我在下面描述:
MouseArea {
anchors.fill: parent
preventStealing: true
property real reaSpeed: 0.0 // calculates drag speed for swipe to run
property int intStartY: 0 // starting point pressed by the user's finger
property bool booTracing: false //controls the analyzed drag length
onPressed: {
intStartY = mouse.y;
reaSpeed = 0;
booTracing = true;
}
onPositionChanged: {
if (!booTracing)
{
return;
}
reaSpeed = (intStartY - mouse.y) / 2.0;
if ((reaSpeed > 50) && (mouse.y < (parent.height * 0.2)))
{
booTracing = false;
if (booIsShowMenu)
{
sigStartHideMenu();
}
funSwipeScreens("bottom");
}
}
}
我正在检查一种处理 MouseAreas 覆盖的方法。