Paint on rectangle using mouse area qml(Qt-5 ubuntu) [solved]
-
-
Do you want to draw a line on the rectangle following the mouse, or do you want to drag a rectangle?
-
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.1Canvas {
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 rectangeClicking 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 itMain.qml
@
import QtQuick 2.0Rectangle {
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.0Rectangle {
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.0Rectangle {
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.