Paint on rectangle using mouse area qml(Qt-5 ubuntu) [solved]



  • To paint the rectangle in qml using mouse area. I dont know how to use drag to paint the rectangle. Here is the code i am working with

    @
    Rectangle {
    id: container
    width: 600; height: 200

    MouseArea {
    anchors.fill: parent
    drag.target:
    drag.axis:
     
    }
    }
    

    @



  • Do you want to draw a line on the rectangle following the mouse, or do you want to drag a rectangle?



  • JapieKrekel.I want to draw rectangle and circle.



  • The drag.target and drag.axis of the MouseArea is to let Qt move on Item identified at the drag.target to move over the drag.axis with a min and max value.

    Drawing circles and rectangles can be done using the Canvas element available in QtQuick 2.0 and higher.
    You can then draw on it just like on the HTML5 canvas element.

    Or use QtQuick elements, which is a bit more dirty to make a circle out of a rectange using the radius property.

    Circle:
    @
    Rectangle {
    radius: 50
    width: 2 * radius
    height: 2 * radius
    color: "transparent"
    border.color: "black"
    }
    @

    Rectangle:
    @
    Rectangle {
    width: 50
    height: 100
    color: "transparent"
    border.color: "black"
    }
    @

    But now you also want to involve the Mouse somehow. For me it is not clear yet what you want to do with that. Draw one circle or rectangle where you click, or ...



  • Yes it is really not clear what you want. But if you want to draw on a rectangle, you might want to try using the Canvas element instead. Try this:

    @
    import QtQuick 2.1

    Canvas {
    property int prevX
    property int prevY
    property int lineWidth: 2
    property color drawColor: "black"

    MouseArea {
        id:mousearea
        anchors.fill: parent
        onPressed: {prevX = mouseX ; prevY = mouseY}
        onPositionChanged: requestPaint();
    }
    
    onPaint: {
        var ctx = getContext('2d');
        ctx.beginPath();
        ctx.strokeStyle = drawColor
        ctx.lineWidth = lineWidth
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(mousearea.mouseX, mousearea.mouseY);
        ctx.stroke();
        ctx.closePath();
        prevX = mousearea.mouseX;
        prevY = mousearea.mouseY;
    }
    

    }
    @



  • I am sorry for the confusion. I thought drag option is for mouse . I didnt think about draging the rectangle element in qml. I have to draw a rectange and circle, for example when we move the mouse, the diameter of circle should increase and in the case of the rectangle, its heigh and width should change.
    jens I tried your code , it is showing an error message QtQuick version 2.1 not installed. I am using (Qt Creator 2.6.2 Based on Qt 5.0.1 (32 bit)). I changed the import to QtQuick 2.0 it is running but displaying blank screen with no action. Is canvas available in QtQuick 2.0. Thank you



  • It is available and should work by simply press and dragging the mouse on the rectangle but I do not have 5.0.1 around to verify if there are issues with my example there. There could be a bug that has been fixed so you can start by debugging the onPaint and see if you are getting paint events properly.
    Note that I forgot to set a width and height in the code above so perhaps you simply have to set those properties to say 400 in my example to make it work.

    In your case you might not have to use a canvas though since you can easily draw both a rectangle or circle without it. I would suggest that you start to read a bit about how MouseArea works in the documentation :)



  • Jens thank you. I have added width and height in canvas element. I don't know how to call request paint function in qml. should I have to use qquick view. I am getting an error message requestPaint is not defined. I can understand there is no requestPaint fuction in my file and I also dont know how to call.



  • Jens thank you very much it is working. When I put that inside a rectangle element it is showing an error message Error: Invalid write to global property "prevX" and ReferenceError: requestPaint is not defined.

    @
    import QtQuick 2.0
    Rectangle{
    width:400
    height:500
    color:"blue"

    Canvas {
    property int prevX
    property int prevY
    property int lineWidth: 2
    property color drawColor: "red"

    width: 400
    height: 500
    
    MouseArea {
        id:mousearea
        anchors.fill: parent
        onPressed: {prevX = mouseX ; prevY = mouseY}
        onPositionChanged: requestPaint();
    }
    
    onPaint: {
        var ctx = getContext('2d');
        ctx.beginPath();
        ctx.strokeStyle = drawColor
        ctx.lineWidth = lineWidth
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(mousearea.mouseX, mousearea.mouseY);
        ctx.stroke();
        ctx.closePath();
        prevX = mousearea.mouseX;
        prevY = mousearea.mouseY;
    }
    

    }
    }
    @



  • You need to read up on how properties and id's work as this has more to do with QML and not so much to do about the topic. To fix it:

    • Move the four property declarations to the root item
    • Add an "id: canvas" to the top of your canvas
    • Replace "requestPaint()" with "canvas.requestPaint()"


  • jens your code helped me a lot but I am unable to complete it. Here is the problem what i am facing. I could draw the rectangle in one direction when I move it back number of rectangle images are getting overlayed. Here is the code

    @

    import QtQuick 2.0

    Rectangle{
    width:900
    height:900
    color:"blue"

    property int prevX
    property int prevY
    property int lineWidth: 2
    property color drawColor: "red"
    
    
    Canvas {
        id:mycanvas
        width: 900
        height: 900
    
        MouseArea {
            id:mousearea
            anchors.fill: parent
            onPressed: {
                prevX = mouseX ; prevY = mouseY
            }
    
            onPositionChanged: mycanvas.requestPaint();
        }
    
    
        onPaint: {
            var ctx = getContext('2d');
            ctx.beginPath();
            ctx.strokeStyle = drawColor
            ctx.lineWidth = lineWidth
            ctx.rect(prevX, prevY, mousearea.mouseX-prevX,mousearea.mouseY-prevY);
            ctx.clearRect(prevX, prevY, mousearea.mouseX-prevX,mousearea.mouseY-prevY);
            ctx.stroke();
        }
    
    }
    

    }
    @

    In case of circle I am still struggling. I dont know how to clear the tracks formed by circle

    @

    import QtQuick 2.0

    Rectangle{
    width:900
    height:900
    color:"blue"

    property int prevX
    property int prevY
    property int lineWidth: 2
    property color drawColor: "red"
    
    
    Canvas {
        id:mycanvas
        width: 900
        height: 900
    
        MouseArea {
            id:mousearea
            anchors.fill: parent
            onPressed: {
                prevX = mouseX ; prevY = mouseY
            }
    
            onPositionChanged: mycanvas.requestPaint();
        }
    
    
        onPaint: {
            var ctx = getContext('2d');
            ctx.beginPath();
            ctx.strokeStyle = drawColor
            ctx.lineWidth = lineWidth
            ctx.arc(prevX,prevY,mousearea.mouseX-prevX,1,360,true);
            ctx.stroke();
        }
    
    }
    

    }

    @

    Thank you :-)



  • I did some playing around doing it without a canvas and cooked something up as seen below.

    Clicking left on the main screen will draw a circle
    Clicking right on the main screen will draw a rectange

    Clicking left on a circle or rectangle and then move the mouse, will move the object
    Clicking right on it and move will resize it
    Double click on it will delete it

    Main.qml
    @
    import QtQuick 2.0

    Rectangle {
    width: 600
    height: 500
    MouseArea {
    anchors.fill: parent
    acceptedButtons: Qt.LeftButton | Qt.RightButton
    onClicked: {
    if (mouse.button === Qt.LeftButton)
    Qt.createComponent("MyCircle.qml").createObject(parent, {x: mouseX, y: mouseY})
    if (mouse.button === Qt.RightButton)
    Qt.createComponent("MyRect.qml").createObject(parent, {x: mouseX, y: mouseY})
    }
    }
    }
    @

    MyRect.qml
    @
    import QtQuick 2.0

    Rectangle {
    id: rect
    color: "yellow"
    border.color: "black"

    width: 50
    height: 50
    MouseArea {
        anchors.fill: parent
        acceptedButtons:  Qt.LeftButton | Qt.RightButton
        onDoubleClicked: rect.destroy();
        onPositionChanged: {
            if (mouse.buttons & Qt.LeftButton) {
                rect.x -= (x - mouse.x); rect.y -= (y - mouse.y)
            }
            if (mouse.buttons &  Qt.RightButton) {
                rect.width = Math.abs(x - mouseX); rect.height = Math.abs(y - mouseY)
            }
        }
    }
    

    }
    @

    MyCircle.qml
    @
    import QtQuick 2.0

    Rectangle {
    id: circle
    radius: 50
    width: 2 * radius
    height: 2 * radius
    color: "yellow"
    border.color: "black"

    MouseArea {
        anchors.fill: parent
        acceptedButtons:  Qt.LeftButton | Qt.RightButton
        onDoubleClicked: circle.destroy();
    
        onPositionChanged: {
            if (mouse.buttons & Qt.RightButton) {
                circle.radius = Math.abs(x - mouseX);
            }
            if (mouse.buttons & Qt.LeftButton) {
                circle.x -= (x - mouse.x); circle.y -=  (y - mouse.y)
            }
        }
    }
    

    }
    @

    I hope it helps.



  • JapieKrekel. Thank you :-)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.