簡體   English   中英

如何通過按和拖動在QtQuick / QML畫布中繪制矩形

[英]How to draw a rectangle in QtQuick/QML canvas by press and draging

我想在圖像的頂部繪制一些矩形,該矩形由QQuickPaintedItem子類繪制並在QML中創建。 我使用畫布繪制矩形,可以使用鼠標將其平移並隨圖像縮放。 以下代碼不起作用:

 Canvas{
    id:canvas
    anchors.fill:parent
    // zoom in/out managed by mouse wheel
    property double dx:0.0
    property double dy:0.0
    property double sx:1.0
    property double sy:1.0
    // mapped mouse position will be displayed on the left top of the window
    property double mx:0
    property double my:0
    // mapped mouse postion when last left buttion pressed
    property double lastx:0.0
    property double lasty:0.0
    // flag
    property bool drawing:false

    // map x,y to my coordinate
    function mapToPaint(x,y)
    {
        var mx=(x-dx)/sx;
        var my=(y-dy)/sy;
        return {"x":mx,"y":my};
    }


    onPaint:{
        var ctx = canvas.getContext("2d");
        ctx.lineWidth = 1
        ctx.strokeStyle = Qt.lighter(root.color)
        ctx.clearRect (0, 0, width, height);
        ctx.save();
        // transform to my coordinate
        ctx.translate(dx,dy);
        ctx.scale(sx,sy);
        // draw a rect
        // !! I hope drawing can be displayed when mouse moving,
        // !! but the rect wasn't displayed after the mouse button 
        // !! was released. Instead many rectangles will be showed when 
        // !! I rolled the mouse wheel after the press-drag operation.
        if(drawing)
            ctx.rect(lastx,lasty,mx-lastx,my-lasty);
        ctx.stroke();
        ctx.restore();
}
MouseArea {
    id:area
    anchors.fill: parent
    hoverEnabled:true
    preventStealing:true
    property double factor: 1.2
    onPressed:
    {

        if (mouse.button == Qt.LeftButton)
        {
            var p=canvas.mapToPaint(mouse.x,mouse.y);
            canvas.lastx=p.x;
            canvas.lasty=p.y;
            canvas.drawing=true
        }
    }

    onWheel:
    {
        if(wheel.angleDelta.y > 0)  // zoom in
            var zoomFactor = factor
        else                        // zoom out
            zoomFactor = 1/factor   

        canvas.sx*=zoomFactor;
        canvas.sy*=zoomFactor;
        canvas.dx=wheel.x-(wheel.x-canvas.dx)*zoomFactor;
        canvas.dy=wheel.y-(wheel.y-canvas.dy)*zoomFactor;
        canvas.requestPaint();
    }
    onPositionChanged:
    {
        var p=canvas.mapToPaint(mouse.x,mouse.y);
        canvas.mx=p.x;
        canvas.my=p.y;
        // I hope the rectangle can be showed when draging
        // but it didn't work!! why?
        // mouse.button == Qt.LeftButton is always false!!!
        // so I have to use the canvas.drawing flag
        // if (mouse.button == Qt.LeftButton)
        if(canvas.drawing)
            canvas.requestPaint();
    }

當我按下並拖動鼠標時,得到以下圖片:

這里

更新:

使用ctx.strokeRect而不是ctx.rect,我得到了右邊的矩形,但是仍然無法在onPositionChanged中接收鼠標按鈕。

這里

通常,如果需要實時預覽矩形(或任何其他對象)時要執行的操作,則需要創建一個臨時矩形以在單擊畫布時在其上方繪制,而僅移動鼠標即可。將該矩形調整為鼠標位置增量的大小,然后放開鼠標,即可在畫布上實際繪制該矩形並刪除預覽。

那就是我要做的,並且在QML中創建一個臨時矩形非常簡單,因此我想您自己實現就可以了嗎?

您當然可以在畫布上繪制所有更新,但是我想,由於刪除最后一個更新並不容易,因此使用此方法進行臨時覆蓋會更容易。

//handle Painted
Canvas{
    id:canvas
    anchors.fill:parent
    // zoom in/out managed by mouse wheel
    property double dx:0.0
    property double dy:0.0
    property double sx:1.0
    property double sy:1.0
    // mapped mouse position will be displayed on the left top of the window
    property double mx:0
    property double my:0
    // mapped mouse postion when last left buttion pressed
    property double lastx:0.0
    property double lasty:0.0
    // flag
    property bool drawing:false

    // map x,y to my coordinate
    function mapToPaint(x,y)
    {
        var mx=(x-dx)/sx;
        var my=(y-dy)/sy;
        return {"x":mx,"y":my};
    }

    function clear(){
        var ctx = canvas.getContext("2d");
        ctx.reset();
        canvas.requestPaint();

    }
    onPaint:{
        var ctx = canvas.getContext("2d");
        ctx.lineWidth = 1
        ctx.strokeStyle = 'blue'

        ctx.save();
        // transform to my coordinate
        ctx.translate(dx,dy);
        ctx.scale(sx,sy);
        // draw a rect
        // !! I hope drawing can be displayed when mouse moving,
        // !! but the rect wasn't displayed after the mouse button
        // !! was released. Instead many rectangles will be showed when
        // !! I rolled the mouse wheel after the press-drag operation.

        if(drawing)
            ctx.rect(lastx,lasty,mx-lastx,my-lasty);
        ctx.stroke();
        ctx.restore();

    }
}

    MouseArea {
        id:area
        anchors.fill: parent
        hoverEnabled:true
        preventStealing:true
        property double factor: 1.2
        onPressed:
        {


            var p=canvas.mapToPaint(mouse.x,mouse.y);
            canvas.lastx=p.x;
            canvas.lasty=p.y;
            canvas.drawing=true

        }

        onPositionChanged:
        {
            canvas.clear();
            var p=canvas.mapToPaint(mouse.x,mouse.y);
            canvas.mx=p.x;
            canvas.my=p.y;
            // I hope the rectangle can be showed when draging
            // but it didn't work!! why?
            // mouse.button == Qt.LeftButton is always false!!!
            // so I have to use the canvas.drawing flag
            // if (mouse.button == Qt.LeftButton)
            if(canvas.drawing)
                canvas.requestPaint();
        }
        onReleased: {
            canvas.clear();
            console.log(canvas.lastx,canvas.lasty,canvas.mx,canvas.my);
            canvas.drawing=false
        }

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM