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

Posted

技术标签:

【中文标题】如何通过拖动来旋转 qml 矩形?【英文标题】:How to rotate a qml rectangle by dragging? 【发布时间】:2013-06-24 12:30:31 【问题描述】:

我正在创建一个时钟计时器,可以通过拖动时钟指针(使用触摸输入或鼠标)来设置时间。为此,我定义了一个 AnalogClockHand 元素,如下所示,

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 
        
    

在主 qml 文件中,我使用了这个元素并为其添加了一个 mouseArea,如下所示,

主 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;
                               
        
    

但是,此逻辑无法正常工作并且非常不稳定。所以不能把时间设置得那么顺利。归根结底,我正在尝试实现如下图所示的东西。用户应该能够移动时针、分针或秒针来设置时间。

有没有更好的代码逻辑可以实现?

注意 1:我确实意识到图像中的秒针非常小,但应该尽快修复。

【问题讨论】:

【参考方案1】:

我会这样做(我做了一个更简单的代码,因为我没有 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;
        
    

工作正常!


上面例子的输出

【讨论】:

以上是关于如何通过拖动来旋转 qml 矩形?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过按下和拖动在 Qt Quick/QML 画布中绘制一个矩形

QML 拖放机制可以在不移动拖动项的情况下工作吗?

通过在Android中拖动矩形的角来更改矩形的大小?

Android:通过拖动图像的特定部分来旋转图像

如何在 MouseArea 拖动上平移 QML 项目

ps5用裁剪工具拖动四个角的点,怎么防止图像变形。