简体   繁体   English

如何通过拖动来旋转qml矩形?

[英]How to rotate a qml rectangle by dragging?

I am creating a clock timer where the time can be set by dragging the clock hand (using touch input or mouse). 我正在创建一个时钟计时器,通过拖动时钟指针(使用触摸输入或鼠标)设置时间。 For this purpose I have defined a AnalogClockHand element as shown below, 为此,我定义了一个AnalogClockHand元素,如下所示,

AnalogClockHand.qml AnalogClockHand.qml

Rectangle {
    id: hand

    property alias rotationAngle: handRotation.angle

    x: (parent.width / 2) - (width / 2); y: (parent.height / 2) - height; z: 2
    width: units.gu(1); height: units.gu(14);
    radius: units.gu(1)
    color: Constants.coolGrey
    antialiasing: true

    transform: Rotation {
        id: handRotation

        origin { x: hand.width / 2; y: hand.height }    
        Behavior on angle {
            SpringAnimation { spring: 2; damping: 0.3; modulus: 360 }
        }
    }
}

In the main qml file, I used this element and add a mouseArea to it as shown below, 在主qml文件中,我使用了这个元素并向其添加了一个mouseArea,如下所示,

Main Qml File 主Qml文件

AnalogClockHand {
        id: secondHand

        z: parent.z - 1;
        height: units.gu(17); width:  units.gu(0.5)
        rotationAngle: seconds * 6;
        antialiasing: true;

        // Implements touch support
        MouseArea {
            id: timerbackmousearea

            property real truex: mouseX - parent.width/2
            property real truey: parent.height/2 - mouseY
            property real angle: Math.atan2(truex, truey)
            property real strictangle: parseInt(angle * 180 / Math.PI)
            property real modulo: strictangle % 6

            anchors.fill: parent
            preventStealing: true

            onPositionChanged: if (timerbackmousearea.angle < 0) {
                                   secondHand.rotationAngle = strictangle - modulo + 360;
                                   timerValue = parseInt(secondHand.rotationAngle/6);
                                   seconds = timerValue;
                               }
                               else {
                                   secondHand.rotationAngle = strictangle - modulo + 6;
                                   timerValue = parseInt(secondHand.rotationAngle/6);
                                   seconds = timerValue;
                               }
        }
    }

This logic is however not working properly and is very flaky. 然而,这种逻辑不能正常工作并且非常不稳定。 So one cannot set the time as smoothly. 因此,人们无法顺利地设定时间。 At the end of the day, I am trying to implement something as shown in the image below. 在一天结束时,我正在尝试实现如下图所示的内容。 The user should be able to move the hour, minute or seconds hand to set the time. 用户应该能够移动小时,分钟或秒针来设置时间。

Is there a better code logic that I could implement ? 是否有更好的代码逻辑可以实现?

Note 1: I do realise that the second hand is very small in the image, but that should be fixed soon enough. 注1:我确实认识到秒针在图像中非常小,但应该尽快修复。

在此输入图像描述

I would do it like this (i did a simpler code as I don't have Ubuntu Touch Components), but the rotation logic is here and the angle to second conversion too : 我会这样做(我做了一个更简单的代码,因为我没有Ubuntu Touch组件),但旋转逻辑在这里和第二次转换的角度:

import QtQuick 2.0

Rectangle{
    id: root;
    width: 720;
    height: 480;
    color: "black";

    Item {
        id: container;
        width: 250;
        height: width;
        anchors.centerIn: parent;

        property real centerX : (width / 2);
        property real centerY : (height / 2);

        Rectangle{
            id: rect;
            color: "white";
            transformOrigin: Item.Center;
            radius: (width / 2);
            antialiasing: true;
            anchors.fill: parent;

            Rectangle {
                id: handle;
                color: "red";
                width: 50;
                height: width;
                radius: (width / 2);
                antialiasing: true;
                anchors {
                    top: parent.top;
                    margins: 10;
                    horizontalCenter: parent.horizontalCenter;
                }

                MouseArea{
                    anchors.fill: parent;
                    onPositionChanged:  {
                        var point =  mapToItem (container, mouse.x, mouse.y);
                        var diffX = (point.x - container.centerX);
                        var diffY = -1 * (point.y - container.centerY);
                        var rad = Math.atan (diffY / diffX);
                        var deg = (rad * 180 / Math.PI);
                        if (diffX > 0 && diffY > 0) {
                            rect.rotation = 90 - Math.abs (deg);
                        }
                        else if (diffX > 0 && diffY < 0) {
                            rect.rotation = 90 + Math.abs (deg);
                        }
                        else if (diffX < 0 && diffY > 0) {
                            rect.rotation = 270 + Math.abs (deg);
                        }
                        else if (diffX < 0 && diffY < 0) {
                            rect.rotation = 270 - Math.abs (deg);
                        }
                    }
                }
            }
        }
        Text {
            text: "%1 secs".arg (Math.round (rect.rotation / 6));
            font {
                pixelSize: 20;
                bold: true;
            }
            anchors.centerIn: parent;
        }
    }
}

Works fine ! 工作良好 !


Output for the above example 以上示例的输出

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM