【问题标题】:How to draw a rectangle in QtQuick/QML canvas by press and draging如何通过按下和拖动在 Qt Quick/QML 画布中绘制一个矩形
【发布时间】:2017-03-27 12:50:02
【问题描述】:

我想在图像顶部绘制一些矩形,这些矩形由 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();
    }

当我按下并拖动鼠标时,我得到了以下图片:

here

更新:

使用 ctx.strokeRect 代替 ctx.rect,我得到了正确的矩形,但在 onPositionChanged 中仍然无法接收到鼠标按钮。

here

【问题讨论】:

    标签: javascript qt canvas qml qtquick2


    【解决方案1】:

    一般来说,如果您需要实时预览矩形(或任何其他对象),您需要创建一个临时矩形,以便在单击画布时在画布上进行绘制,同时移动鼠标,您只需将该矩形调整为鼠标位置增量的大小,当您松开鼠标时,您实际上在画布上绘制矩形并删除预览。

    这就是我要做的,在 QML 中创建一个临时矩形非常简单,所以我想你自己实现它应该没问题?

    您当然可以在画布上绘制所有更新,但由于仅删除最后一个更新并不容易,因此我猜使用这种带有临时叠加层的方法会更容易。

    【讨论】:

      【解决方案2】:
      //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
              }
      
          }
      

      【讨论】:

      • 您好,请在发布的代码中添加一些说明。
      猜你喜欢
      • 1970-01-01
      • 2020-10-13
      • 1970-01-01
      • 2012-06-16
      • 1970-01-01
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多