QML-使用箭头键移动项目

时间:2016-05-07 07:20:25

标签: qt qml

我在Windows 8.1中使用Qt 5.6.0版。我画了一个有4个边和能够拖动它的顶点的形状。我想用箭头键移动形状的顶点。我使用这个代码但它不起作用。 Point.qml:

Item {
id: root

signal dragged()
property alias color :point.color
Rectangle {
    id:point
    anchors.centerIn: parent
    width: 20
    height: 20

    opacity: 0.2

    MouseArea {
        anchors.fill: parent
        drag.target: root
        onPositionChanged: {
            if(drag.active) {
                dragged()
            }
        }
        onClicked: point.focus=true;
    }

    //        Keys.onPressed: {
    //            console.log("move");
    //            if (event.key === Qt.Key_Left) {
    //                console.log("move left");
    //                event.accepted = true;
    //                point.x-=1;
    //            }
    //        }
    //        Keys.onRightPressed: {
    //            console.log("move");
    //            point.x+=1;
    //        }

    //        Keys.onLeftPressed: {
    //            console.log("move");
    //            point.x-=1;
    //        }
    Keys.onPressed: {
        switch(event.key) {
        case Qt.Key_Left: point.x-=1;
            break;
        case Qt.Key_Right: point.x+=1;
            break;
        case Qt.Key_Up: point.y-=1;
            break;
        case Qt.Key_Down: point.y+=1;
            break;
        }
    }

    focus: true;
}}

main.qml:

 Point {
    id: pointA
    x: 50
    y: 50
}

Point {
    id: pointB
    x: 250
    y: 50
}

Point {
    id: pointC
    x: 250
    y: 250
}

Point {
    id: pointD
    x: 50
    y: 250
}


Item {
    anchors.fill: parent

    Canvas {
        id: canvas
        anchors.fill: parent
        onPaint: {
            var ctx = canvas.getContext('2d');
            ctx.moveTo(pointA.x, pointA.y);
            ctx.lineTo(pointB.x, pointB.y);
            ctx.lineTo(pointC.x, pointC.y);
            ctx.lineTo(pointD.x, pointD.y);
            ctx.lineTo(pointA.x, pointA.y);
            ctx.stroke();
        }
        Component.onCompleted: {
            pointA.dragged.connect(repaint)
            pointB.dragged.connect(repaint)
            pointC.dragged.connect(repaint)
            pointD.dragged.connect(repaint)
        }

        function repaint() {
            var ctx = getContext("2d");
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.beginPath();
            requestPaint()
        }
    }
}

更新: main.qml:

PhotoPreview {
                            id : photoPreview
                            anchors.fill : parent
                            //focus:true //visible
                            visible: capture
                        }

photopreview.qml:

Item {
  id:mywin    
  property real defaultSize:mywin.width
property var currentFrame: undefined
property real surfaceViewportRatio: 1.5
focus: true    
ScrollView {
    anchors.fill: parent
    flickableItem.interactive: true
    frameVisible: true
    highlightOnFocus: true           
    Flickable {
        id: flick
        anchors.fill: parent
        contentWidth: parent.width
        contentHeight: parent.height
        property alias source :image.source
        signal closed
        Rectangle {
            id: photoFrame
            width: parent.width
            height: parent.height
            color:"transparent"
            scale:defaultSize / parent.width
            Behavior on scale { NumberAnimation { duration: 200 } }
            Behavior on x { NumberAnimation { duration: 200 } }
            Behavior on y { NumberAnimation { duration: 200 } }                
            smooth: true
            antialiasing: true                
            Image {
                id:image
                anchors.fill: parent
                fillMode: Image.PreserveAspectFit
                smooth: true
            }
            PinchArea {
                anchors.fill: parent
                pinch.target: photoFrame
                pinch.minimumRotation: -360
                pinch.maximumRotation: 360
                pinch.minimumScale: 0.1
                pinch.maximumScale: 10
                pinch.dragAxis: Pinch.XAndYAxis
                property real zRestore: 0
                onSmartZoom: {
                    if (pinch.scale > 0) {
                        photoFrame.rotation = 0;
                        photoFrame.scale = Math.min(mywin.width, mywin.height) / Math.max(image.sourceSize.width, image.sourceSize.height) * 0.85
                        photoFrame.x = flick.contentX + (flick.width - photoFrame.width) / 2
                        photoFrame.y = flick.contentY + (flick.height - photoFrame.height) / 2
                        zRestore = photoFrame.z
                        photoFrame.z = ++mywin.highestZ;
                    } else {
                        photoFrame.rotation = pinch.previousAngle
                        photoFrame.scale = pinch.previousScale
                        photoFrame.x = pinch.previousCenter.x - photoFrame.width / 2
                        photoFrame.y = pinch.previousCenter.y - photoFrame.height / 2
                        photoFrame.z = zRestore
                        --mywin.highestZ
                    }
                }                    
                MouseArea {
                    id: dragArea
                    hoverEnabled: true
                    anchors.fill: parent
                    drag.target: photoFrame
                    scrollGestureEnabled: false  // 2-finger-flick gesture should pass through to the Flickable
                    onPressed: {
                        photoFrame.z = ++mywin.highestZ;
                    }                        
                    onWheel: {
                        if (wheel.modifiers & Qt.ControlModifier) {
                            photoFrame.rotation += wheel.angleDelta.y / 120 * 5;
                            if (Math.abs(photoFrame.rotation) < 4)
                                photoFrame.rotation = 0;
                        } else {
                            photoFrame.rotation += wheel.angleDelta.x / 120;
                            if (Math.abs(photoFrame.rotation) < 0.6)
                                photoFrame.rotation = 0;
                            var scaleBefore = photoFrame.scale;
                            photoFrame.scale += photoFrame.scale * wheel.angleDelta.y / 120 / 10;
                        }
                    }
                }
            }                
            Point {
                id: pointA
                x: image.width/4
                y: image.height/4
                color: "blue"
            }
            Point {
                id: pointB
                x: image.width/2
                y: image.height/2
                color: "blue"                    
            }                
            Point {
                id: pointD
                x: image.width/4
                y: image.height/2
                color: "red"
            }                
            Point {
                id: pointC
                x: image.width/2
                y: image.height/4
                color: "red"                    
            }                
            Item {
                anchors.fill: parent                    
                Canvas {
                    id: canvas
                    anchors.fill: parent                        
                    onPaint: {
                        //...
                    }
                    Component.onCompleted: {
                        //...
                    }                        
                    function repaint() {
                        //..
                    } 
                }
            }
        }
    }
}}

2 个答案:

答案 0 :(得分:3)

您正在使用ScrollView继承FocusScopefocus:true需要focusforward it。 相反,您将PhotoPreview设置为Item,这是普通的focus:visible,不应该被关注。

因此,您需要简单地删除ScrollView并将其设置为Item

更好的解决方法是删除多余的ScrollView,并将PhotoPreview保留为{{1}}根项目及其所有属性和信号。

答案 1 :(得分:2)

Point.qml中,键事件处理程序尝试更改point的x,y,但pointanchors.centerIn: parent的矩形。关键事件处理程序应该更改root x,y而不是:

//in Point.qml
case Qt.Key_Left: 
    root.x-=1;
    break;

Point现在在触发键盘事件时更改其位置。接下来,Point需要通知Canvas中的main.qml进行重新绘制。 Point更改了x,y后发出dragged信号:

//in Point.qml
Keys.onPressed: {
    switch(event.key) {
    case Qt.Key_Left: 
        root.x-=1;
        dragged();
        break;
    case Qt.Key_Right: 
        root.x+=1;
        dragged();
        break;
    case Qt.Key_Up: 
        root.y-=1;
        dragged();
        break;
    case Qt.Key_Down: 
        root.y+=1;
        dragged();
        break;
    }
}