I have a frameless window I am using MouseArea to allow it to be resizeable. It is working for the most part (I need to add some more resize handles). However, if I drag the window to the top or side on Windows it doesn't 'snap' like a framed one would to filling half the screen or filling the fullscreen. Is there a way with QML to handle this I've heard there is a WM_CHITTEST event I could potentially handle, but how would one be able to respond to a native event like this in QML?
import QtQuick 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 2.12
import QtQuick.Window 2.12
import "Themes"
ApplicationWindow
{
id: mainWindow
width: 640
height: 480
visible: true
color: Theme.primaryBackgroundColor
title: qsTr("SmartDraw")
flags: Qt.FramelessWindowHint | Qt.Window
readonly property real grabThickness: 4
header: Rectangle {
id: windowHeader
height: 38
width: parent.width
color: Theme.secondaryBackgroundColor
MouseArea {
id: windowResizeTopLeft
width: mainWindow.grabThickness
height: mainWindow.grabThickness
anchors.top: parent.top
anchors.left: parent.left
cursorShape: Qt.SizeFDiagCursor
property point lastMousePos: Qt.point(0,0)
onPressed: {
lastMousePos = Qt.point(mouse.x,mouse.y)
}
onMouseXChanged: {
var dx = (mouseX - lastMousePos.x)
mainWindow.x += dx
mainWindow.width -= dx
}
onMouseYChanged: {
var dy = (mouseY - lastMousePos.y)
mainWindow.y += dy
mainWindow.height -= dy
}
}
MouseArea {
id: windowResizeUp
height: mainWindow.grabThickness
anchors.top: parent.top
anchors.left: windowResizeTopLeft.right
anchors.right: minimize.left
cursorShape: Qt.SizeVerCursor
property real lastMousePosY: 0
onPressed: {
lastMousePosY = mouse.y
}
onMouseYChanged:
{
var dy = (mouseY - lastMousePosY)
mainWindow.y += dy
mainWindow.height -= dy
}
}
MouseArea {
id: windowDragArea
height: parent.height - mainWindow.grabThickness
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: minimize.left
property point lastMousePos: Qt.point(0, 0)
onPressed: { lastMousePos = Qt.point(mouseX, mouseY); }
onMouseXChanged: mainWindow.x += (mouseX - lastMousePos.x)
onMouseYChanged: mainWindow.y += (mouseY - lastMousePos.y)
}
Button {
id: minimize
width: 30
height: parent.height
anchors.right: maximize.left
onClicked: mainWindow.showMinimized()
background: Rectangle {
width: parent.width
height: parent.height
color: windowHeader.color
}
Rectangle {
color: "white"
height: 2
width: Math.round(parent.width*(2.0/3.0))
anchors.centerIn: parent
}
}
Button {
id: maximize
width: 30
height: parent.height
anchors.right: close.left
onClicked: mainWindow.visibility == Window.Maximized ? mainWindow.showNormal() : mainWindow.showMaximized()
background: Rectangle {
width: parent.width
height: parent.height
color: windowHeader.color
}
Rectangle {
color: "white"
width: 15
height: 15
}
}
Button {
id: close
width: 30
anchors.right: parent.right
height: parent.height
onClicked: Qt.quit()
background: Rectangle {
width: parent.width
height: parent.height
color: windowHeader.color
}
Text {
color: "white"
text: "X"
}
}
}
footer: Rectangle {
id: windowFooter
color: "#0e6afa"
height: 23
MouseArea {
id: windowResizeBottomLeft
width: mainWindow.grabThickness
height: mainWindow.grabThickness
anchors.left: parent.left
anchors.bottom: parent.bottom
cursorShape: Qt.SizeBDiagCursor
property point lastMousePos: Qt.point(0,0)
onPressed: {
lastMousePos = Qt.point(mouse.x,mouse.y)
}
onMouseYChanged:
{
var dx = (mouseX - lastMousePos.x)
var dy = (mouseY - lastMousePos.y)
mainWindow.x += dx
mainWindow.width -= dx
mainWindow.height += dy
}
}
MouseArea {
id: windowResizeBottom
x: mainWindow.grabThickness
height: mainWindow.grabThickness
anchors.bottom: parent.bottom
anchors.left: windowResizeBottomLeft.right
anchors.right: windowResizeBottomRight.left
cursorShape: Qt.SizeVerCursor
property real lastMousePosY: 0
onPressed: {
lastMousePosY = mouse.y
}
onMouseYChanged:
{
var dy = (mouseY - lastMousePosY)
mainWindow.height += dy
}
}
MouseArea {
id: windowResizeBottomRight
width: mainWindow.grabThickness
height: mainWindow.grabThickness
anchors.right: parent.right
anchors.bottom: parent.bottom
cursorShape: Qt.SizeFDiagCursor
property point lastMousePos: Qt.point(0,0)
onPressed: {
lastMousePos = Qt.point(mouse.x,mouse.y)
}
onMouseYChanged:
{
var dx = (mouseX - lastMousePos.x)
var dy = (mouseY - lastMousePos.y)
mainWindow.width += dx
mainWindow.height += dy
}
}
}
}
Best way to do this is to use startSystemResize which added to Qt QWindow since 5.15. You can use in different ways, but my specific way is like this :
MouseArea{
id : resizearea
width: 5
height: 5
anchors.bottom: parent.bottom
anchors.right: parent.right
cursorShape: Qt.SizeAllCursor
acceptedButtons: Qt.LeftButton
pressAndHoldInterval: 100
onPressAndHold:
{
mainview.startSystemResize(Qt.BottomEdge | Qt.RightEdge)
}
I think this is the best way to resize frameless window in qml
I am trying to make a scroll bar without using ScrollBar Component in QML.
So i have made this component and attach to the ListView. But it doesn't flick the listview items.
I want, this rectangle scrolls the content of ListView or GridView on scrolling.
What I did?
Ist I create a rectangle then make another rectangle as a child of ist one. And applied the dragging technique on Y axis and set the coordinates for y axis.
My Code is given below:
import QtQuick 2.0
Rectangle{
property bool is_parentDrag: false
property bool is_childDrag: false
id:parent_screen
anchors.fill:parent
color:"#ebeaee"
Rectangle{
id:foot
width:parent.width*0.9
height:parent.height*0.133
color:"#ffffff"
border.width:1
anchors.bottom:parent.bottom
anchors.bottomMargin:lv.height*0.005
anchors.horizontalCenter: parent.horizontalCenter
Rectangle{
width:parent.width*0.125
height:parent.height*0.5
radius:20
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: parent.height*0.2
color:"transparent"
Image{
source: "left_direction_icon.png"
anchors.centerIn: parent
sourceSize.width: parent.width*0.4
sourceSize.height: parent.width*0.4
}
MouseArea{
anchors.fill:parent
onClicked: {
stack.pop()
}
}
}
}
Flickable{
id:flick_1
width:parent.width*0.9
height:parent.height*0.7
anchors.centerIn: parent
flickableDirection:Flickable.HorizontalFlick
boundsBehavior: Flickable.StopAtBounds
ListView{
id:lv
clip:true
boundsBehavior: Flickable.StopAtBounds
height:parent.height
width:parent.width*0.9
anchors.left:parent.left
anchors.leftMargin: parent.width*0.11
model:Data{}
delegate: Rectangle{
id:delg
width:lv.width*0.5
height:lv.height*0.170
Text{
text:txt
anchors.centerIn: parent
font.pixelSize: 22
}
Rectangle{
id:right
width:1
height:parent.height
color:"black"
anchors.right:parent.right
}
Rectangle{
id:bottom
width:parent.width
height:1
color:"black"
anchors.bottom:parent.bottom
}
Rectangle{
id:left
width:1
height:parent.height
color:"black"
anchors.left:parent.left
}
}
Rectangle{
id:scrollbar
width:flick_1.width*0.02
height:flick_1.height
visible: lv.contentHeight>lv.height
radius:width/2
color:"lightgrey"
anchors.right: lv.right
anchors.rightMargin: lv.width*0.1
Rectangle {
id:scroll
Drag.active:is_parentDrag?parent_drag_area.drag.active:is_childDrag?drag_area.drag.active:false
Drag.source: scroll
implicitWidth: parent.width
implicitHeight: parent.height*0.7
radius:width/2
opacity:0.85
color: "grey"
MouseArea{
id:drag_area
anchors.fill:parent
drag.target: scroll
drag.axis: Drag.YAxis
drag.minimumY: 0
drag.maximumY: scrollbar.height-scroll.height
onPressed:{
if(is_childDrag)
is_childDrag=false
else
is_childDrag=true
}
}
}
MouseArea{
id:parent_drag_area
anchors.fill:parent
drag.target: scroll
drag.axis: Drag.YAxis
drag.minimumY: 0
drag.maximumY: scrollbar.height-scroll.height
onPressed:{
if(is_parentDrag)
is_parentDrag=false
else
is_parentDrag=true
}
}
}
// Rectangle {
// id: scrollbar
// //height:parent.height*0.04
// width:parent.width
// radius:width/2
// anchors.bottom: parent.bottom
// y: flick_1.visibleArea.yPosition * flick_1.height
// height: flick_1.visibleArea.heightRatio * flick_1.height*0.04
// color: "lightgrey"
// anchors.bottomMargin: parent.height*0.1
// Rectangle {
// id:scroll
// y: flick_1.visibleArea.yPosition * flick_1.height
// implicitWidth: parent.width*0.7
// implicitHeight: parent.height
// radius:width/2
// opacity:0.85
// color: "grey"
// }
// }
}
}
}
You can try this (copied from QML Material Project).
Create a new QML-File called ScrollbarCustom.qml:
Item {
id: root
property Flickable flickableItem
property int orientation: Qt.Vertical
property int thickness: 5
property bool moving: flickableItem.moving
property alias currentY: scrollBar.y
width: thickness
height: thickness
clip: true
smooth: true
visible: orientation === Qt.Vertical ? flickableItem.contentHeight > flickableItem.height
: flickableItem.contentWidth > flickableItem.width
anchors {
top: orientation === Qt.Vertical ? flickableItem.top : undefined
bottom: flickableItem.bottom
left: orientation === Qt.Horizontal ? flickableItem.left : undefined
right: flickableItem.right
margins: 2
}
signal stopAnimation
onStopAnimation: {
hideAnimation.stop();
showAnimation.start();
}
signal startAnimation
onStartAnimation: {
hideAnimation.start();
showAnimation.stop();
}
Component.onCompleted: hideAnimation.start()
onMovingChanged: {
if (moving) {
hideAnimation.stop()
showAnimation.start()
} else {
hideAnimation.start()
showAnimation.stop()
}
}
NumberAnimation {
id: showAnimation
target: scrollBar;
property: "opacity";
to: 0.3;
duration: 200;
easing.type: Easing.InOutQuad
}
SequentialAnimation {
id: hideAnimation
NumberAnimation { duration: 500 }
NumberAnimation {
target: scrollBar;
property: "opacity";
to: 0;
duration: 500;
easing.type: Easing.InOutQuad
}
}
onOrientationChanged: {
if (orientation == Qt.Vertical) {
width = thickness
} else {
height = thickness
}
}
Rectangle {
id: scrollBar
property int length: orientation == Qt.Vertical ? root.height
: root.width;
property int targetLength: orientation == Qt.Vertical ? flickableItem.height
: flickableItem.width;
property int contentStart: orientation == Qt.Vertical ? flickableItem.contentY
: flickableItem.contentX;
property int contentLength: orientation == Qt.Vertical ? flickableItem.contentHeight
: flickableItem.contentWidth;
property int start: Math.max(0, length * contentStart/contentLength);
property int end: Math.min(length,
length * (contentStart + targetLength)/contentLength)
color: Theme.accentColor //"black"//theme.foreground
opacity: 0.2
radius: thickness/2
width: Math.max(orientation == Qt.Horizontal ? end - start : 0, thickness)
height: Math.max(orientation == Qt.Vertical ? end - start : 0, thickness)
x: orientation == Qt.Horizontal ? start : 0
y: orientation == Qt.Vertical ? start : 0
}
}
And use it like this:
Flickable {
id: flickable
clip: true
anchors {
top: parent.top
left: parent.left
right: parent.right
bottom: parent.bottom
}
}
ScrollbarCustom {
flickableItem: flickable
}
A solution is to leverage Qt Quick Templates 2. This Qt module is the base of Qt own controls Qt Quick Controls 2 and contains multiple base UI components that can be fully customized.
In your case, you should look at ScrollBar and how to customize it.
Your code could end up being something like this:
Flickable {
id: flickable
clip: true
// ...
ScrollBar.vertical: ScrollBar {
id: control
size: 0.3
position: 0.2
active: true
orientation: Qt.Vertical
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: 100
radius: width / 2
color: control.pressed ? "#81e889" : "#c2f4c6"
}
}
}
I'm trying to make zoomable Item (Image or any other component) and make it for tablet. Currently, my code looks like this:
Rectangle {
id: root
anchors.fill: parent
color: mainWindow.toGradient
Flickable {
id: flick
anchors.fill: parent
contentWidth: width
contentHeight: height
boundsBehavior: Flickable.StopAtBounds
PinchArea {
id: pArea
width: Math.max(flick.contentWidth, flick.width)
height: Math.max(flick.contentHeight, flick.height)
property real initialWidth
property real initialHeight
onPinchStarted: {
initialWidth = flick.contentWidth
initialHeight = flick.contentHeight
}
onPinchUpdated: {
flick.contentX += pinch.previousCenter.x - pinch.center.x
flick.contentY += pinch.previousCenter.y - pinch.center.y
flick.resizeContent(initialWidth * pinch.scale, initialHeight * pinch.scale, pinch.center)
}
onPinchFinished: {
flick.returnToBounds()
}
Rectangle {
width: flick.contentWidth
height: flick.contentHeight
color: "black"
Image {
anchors.fill: parent
source: "qrc:/image.jpg"
}
MouseArea {
anchors.fill: parent
onDoubleClicked: {
flick.contentWidth = root.width
flick.contentHeight = root.height
}
}
}
}
}
}
It works good, but when it's over all screen, i can still zoom out (make it smaller, that parent).
How can I stop zooming out (and if possible zooming in too) at some point/scale?
Thank you for your help!
In the end, I entrily removed Flickable and scaled Item instead.
Rectangle {
id: root
anchors.fill: parent
color: "black"
Item {
id: photoFrame
width: root.width
height: root.height
Image {
id: image
anchors.fill: parent
source: "image.jpg"
}
PinchArea {
anchors.fill: parent
pinch.target: photoFrame
pinch.minimumRotation: 0 //Rotation (i guess we don't need to rotate it)
pinch.maximumRotation: 0
pinch.minimumScale: 1 //Minimum zoom for camera
pinch.maximumScale: 4 //Maximum zoom for camera
onPinchUpdated: { //Dont zoom behind border
if(photoFrame.x < dragArea.drag.minimumX)
photoFrame.x = dragArea.drag.minimumX
else if(photoFrame.x > dragArea.drag.maximumX)
photoFrame.x = dragArea.drag.maximumX
if(photoFrame.y < dragArea.drag.minimumY)
photoFrame.y = dragArea.drag.minimumY
else if(photoFrame.y > dragArea.drag.maximumY)
photoFrame.y = dragArea.drag.maximumY
}
MouseArea {
id: dragArea
hoverEnabled: true
anchors.fill: parent
drag.target: photoFrame
scrollGestureEnabled: false // 2-finger-flick gesture should pass through to the Flickable
drag.minimumX: (root.width - (photoFrame.width * photoFrame.scale))/2
drag.maximumX: -(root.width - (photoFrame.width * photoFrame.scale))/2
drag.minimumY: (root.height - (photoFrame.height * photoFrame.scale))/2
drag.maximumY: -(root.height - (photoFrame.height * photoFrame.scale))/2
onDoubleClicked: { //Reset size and location of camera
photoFrame.x = 0
photoFrame.y = 0
photoFrame.scale = 1
}
onWheel: {
var scaleBefore = photoFrame.scale
photoFrame.scale += photoFrame.scale * wheel.angleDelta.y / 120 / 10
if(photoFrame.scale < 1)
photoFrame.scale = 1
else if(photoFrame.scale > 4)
photoFrame.scale = 4
if(photoFrame.x < drag.minimumX)//Dont zoom behind border of image
photoFrame.x = drag.minimumX
else if(photoFrame.x > drag.maximumX)
photoFrame.x = drag.maximumX
if(photoFrame.y < drag.minimumY)
photoFrame.y = drag.minimumY
else if(photoFrame.y > drag.maximumY)
photoFrame.y = drag.maximumY
}
}
}
}
}
I have a qml map, and a qml quick map item, wen I click on a point on map it places quick map item, well my quick map item is an image which is 300px in 300px, I want to get the coordinate of point(200,200) of image on map, I know that there is a function which is named item.mapToItem(item,x,y), Well I tried to use this function but it returns wrong values,Here is my whole code
Map {
id:map
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(59.91, 10.75) // Oslo
zoomLevel: 7
MapQuickItem{
id:imagQuickitem
zoomLevel:1
sourceItem:Image {
id:image
asynchronous:true
smooth: false
transformOrigin: Item.Center
antialiasing: false
//visible: false
MouseArea{
anchors.fill: parent ;
onPressed:
{
if(!gcplistener && currentTool=="addgcp"){
gcpimgposition=Qt.point(mouse.x,mouse.y);
console.log("The first point is set")
currentgcppoint.row=gcpimgposition.x;
currentgcppoint.column=gcpimgposition.y;
gcplistener=true;
}
console.log(mouse.x + " "+ mouse.y)
console.log( imagQuickitem.mapToItem(map,mouse.x,mouse.y).x+ " "+imagQuickitem.mapToItem(map,mouse.x,mouse.y).y)
console.log( imagQuickitem.mapFromItem(map,mouse.x,mouse.y).x+ " "+imagQuickitem.mapFromItem(map,mouse.x,mouse.y).y)
}
}
}
coordinate: QtPositioning.coordinate(59.91, 10.75)
}
Row {
id: containerRow
layoutDirection: rightEdge() ? Qt.LeftToRight : Qt.RightToLeft
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: rightEdge() ? parent.right : undefined
anchors.left: rightEdge() ? undefined : parent.left
Button {
id: sliderToggler
width: 32
height: 96
checkable: true
checked: true
anchors.verticalCenter: parent.verticalCenter
transform: Scale {
origin.x: rightEdge() ? 0 : sliderToggler.width / 2
xScale: rightEdge() ? 1 : -1
}
style: ButtonStyle {
background: Rectangle {
color: "transparent"
}
}
property real shear: 0.333
property real buttonOpacity: 0.5
property real mirror : rightEdge() ? 1.0 : -1.0
Rectangle {
width: 16
height: 48
color: "seagreen"
antialiasing: true
opacity: sliderToggler.buttonOpacity
anchors.top: parent.top
anchors.left: sliderToggler.checked ? parent.left : parent.horizontalCenter
transform: Matrix4x4 {
property real d : sliderToggler.checked ? 1.0 : -1.0
matrix: Qt.matrix4x4(1.0, d * sliderToggler.shear, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0)
}
}
Rectangle {
width: 16
height: 48
color: "seagreen"
antialiasing: true
opacity: sliderToggler.buttonOpacity
anchors.top: parent.verticalCenter
anchors.right: sliderToggler.checked ? parent.right : parent.horizontalCenter
transform: Matrix4x4 {
property real d : sliderToggler.checked ? -1.0 : 1.0
matrix: Qt.matrix4x4(1.0, d * sliderToggler.shear, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0)
}
}
}
Rectangle {
id: sliderContainer
height: parent.height
width: sliderRow.width + 10
visible: sliderToggler.checked
color: Qt.rgba( 0, 191 / 255.0, 255 / 255.0, 0.07)
property var labelBorderColor: "transparent"
property var slidersHeight : sliderContainer.height
- rowSliderValues.height
- rowSliderLabels.height
- sliderColumn.spacing * 2
- sliderColumn.topPadding
- sliderColumn.bottomPadding
MouseArea{
onPressed: {
console.log("test")
}
}
Column {
id: sliderColumn
spacing: 10
topPadding: 16
bottomPadding: 48
anchors.centerIn: parent
// the sliders value labels
Row {
id: rowSliderValues
spacing: sliderRow.spacing
width: sliderRow.width
height: 32
property real entryWidth: zoomSlider.width
Rectangle{
color: labelBackground
height: parent.height
width: parent.entryWidth
border.color: sliderContainer.labelBorderColor
Label {
id: labelZoomValue
text: zoomSlider.value.toFixed(3)
font.pixelSize: fontSize
rotation: -90
anchors.centerIn: parent
}
}
Rectangle{
color: labelBackground
height: parent.height
width: parent.entryWidth
border.color: sliderContainer.labelBorderColor
Label {
id: labelBearingValue
text: opacityslider.value.toFixed(2)
font.pixelSize: fontSize
rotation: -90
anchors.centerIn: parent
}
}
Rectangle{
color: labelBackground
height: parent.height
width: parent.entryWidth
border.color: sliderContainer.labelBorderColor
Label {
id: labelTiltValue
text: imagescale.value.toFixed(2)
font.pixelSize: fontSize
rotation: -90
anchors.centerIn: parent
}
}
Rectangle{
color: labelBackground
height: parent.height
width: parent.entryWidth
border.color: sliderContainer.labelBorderColor
Label {
id: labelFovValue
text: rotationslider.value.toFixed(2)
font.pixelSize: fontSize
rotation: -90
anchors.centerIn: parent
}
}
} // rowSliderValues
// The sliders row
Row {
spacing: -10
id: sliderRow
height: sliderContainer.slidersHeight
C2.Slider {
id: zoomSlider
height: parent.height
orientation : Qt.Vertical
from : map.minimumZoomLevel
to : map.maximumZoomLevel
value : map.zoomLevel
onValueChanged: {
map.zoomLevel = value
}
}
C2.Slider {
id: opacityslider
height: parent.height
from: 0
to: 1
orientation : Qt.Vertical
value: image.opacity
onValueChanged: {
image.opacity = value;
}
}
C2.Slider {
id: imagescale
height: parent.height
orientation : Qt.Vertical
from: 0;
to: 5
value: image.scale
onValueChanged: {
image.scale= value;
rectangular.scale=value;
}
}
C2.Slider {
id: rotationslider
height: parent.height
orientation : Qt.Vertical
from: 0
to: 360
value: image.rotation
onValueChanged: {
image.rotation = value;
rectangular.rotation=value
}
}
} // Row sliders
// The labels row
Row {
id: rowSliderLabels
spacing: sliderRow.spacing
width: sliderRow.width
property real entryWidth: zoomSlider.width
property real entryHeight: 64
Rectangle{
color: labelBackground
height: parent.entryHeight
width: parent.entryWidth
border.color: sliderContainer.labelBorderColor
Label {
id: labelZoom
text: "Map Zoom"
font.pixelSize: fontSize
rotation: -90
anchors.centerIn: parent
}
}
Rectangle{
color: labelBackground
height: parent.entryHeight
width: parent.entryWidth
border.color: sliderContainer.labelBorderColor
Label {
id: labelBearing
text: "Image Opacity"
font.pixelSize: fontSize
rotation: -90
anchors.centerIn: parent
}
}
Rectangle{
color: labelBackground
height: parent.entryHeight
width: parent.entryWidth
border.color: sliderContainer.labelBorderColor
Label {
id: labelTilt
text: "Image Scale"
font.pixelSize: fontSize
rotation: -90
anchors.centerIn: parent
}
}
Rectangle{
color: labelBackground
height: parent.entryHeight
width: parent.entryWidth
border.color: sliderContainer.labelBorderColor
Label {
id: labelFov
text: "Image Rotation"
font.pixelSize: fontSize
rotation: -90
anchors.centerIn: parent
}
}
} // rowSliderLabels
} // Column
} // sliderContainer
}
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onClicked: mouse.accepted = false;
onReleased: mouse.accepted = false;
onDoubleClicked: mouse.accepted = false;
onPositionChanged: mouse.accepted = false;
onPressAndHold: mouse.accepted = false;
onPressed: {
mouse.accepted = false;
if(imagesourcepoint==null){
imagesourcepoint=Qt.point(mouse.x,mouse.y)
imagQuickitem.coordinate= map.toCoordinate(imagesourcepoint)
rectangular.topLeft=map.toCoordinate(imagesourcepoint);
var w=((image.width*0.0016)+map.toCoordinate(imagesourcepoint).longitude);
var h=(map.toCoordinate(imagesourcepoint).latitude)+(image.height*1.5);
console.log(w)
console.log(h)
if(!image.visible){
image.visible=true
}
}
switch(currentTool){
case "addgcp":
gcppoint=map.toCoordinate(Qt.point(mouse.x,mouse.y));
if(gcplistener){
row.text=gcpimgposition.x;
col.text=gcpimgposition.y;
x.text=gcppoint.longitude;
y.text=gcppoint.latitude;
inputgcpDialog.open();
}else{
currentgcppoint.lat=gcppoint.latitude;
currentgcppoint.lon=gcppoint.longitude;
}
if(gcpimgposition==null&&gcplistener==false){
//user must click on image
//FIXME:
messages.displayMessage("Please click on image, not outside");
}
gcpimgposition==null;
break;
case "moveimage":
//moving image
if(moveimageEnabled){
imagQuickitem.coordinate= map.toCoordinate(Qt.point(mouse.x,mouse.y))
}
break;
}
console.log(map.width + " "+ map.height)
console.log("z: "+map.zoomLevel )
console.log("image.mapToItem: "+ image.mapToItem(map,0,0).x+ " "+image.mapToItem(map,0,0).y)
console.log("image coordinate on map: "+ image.mapToItem(map,image.width,image.height).x+ " "+image.mapToItem(map,image.width,image.height).y)
// console.log( map.mapFromItem(null,0,0).x+ " "+map.mapFromItem(null,0,0).y)
// console.log( map.mapToItem(imagQuickitem,0,0).x+ " "+map.mapToItem(imagQuickitem,0,0).y)
// console.log( map.mapFromItem(imagQuickitem,0,0).x+ " "+map.mapFromItem(imagQuickitem,0,0).y)
onPressed: console.log('latitude = '+ (map.toCoordinate(Qt.point(mouse.x,mouse.y)).latitude),
'longitude = '+ (map.toCoordinate(Qt.point(mouse.x,mouse.y)).longitude));
}
}
}
well, my problem is in part Maps Mouse Area which I expect to get the coordinate of clicked point on Map object based o quickmapitems coordinate using mapToItem function.
My main function is in Mouse pressed button,In above code I expect image.mapToItem(map,0,0).y) to return the same as console.log(mouse.x + " "+ mouse.y) as the mouse.x and mouse.y are the position of (0,0) of image which are mapped on Map items coordinate, I know how to converts maps coordinate to geographic coordinate
I also kept some codes of sliders in map control as I think there must be a relation between these parameters and main map controls mapToItem function
You must call mapToItem() to replace image of imagQuickitem.
Use below code in MouseArea
var coor = image.mapToItem(map , 0 ,0)
Thanks
I want to draw a shape that has 4 sides with unequal length and the ability to drag its apexes. When I dragged an apex, the sides that are connected to it should resize accordingly.
I've found another question on SO but the proposed solution works for Rectangles whereas I would like to develop a solution for trapezoidal shapes, like in the following picture:
My current code:
property var selection: undefined
Image {
id: image1
anchors.fill: parent
source: "1.jpg"
MouseArea {
anchors.fill: parent
onClicked: {
if(!selection)
selection = selectionComponent.createObject(parent, {"x": parent.width / 4, "y": parent.height / 4, "width": parent.width / 2, "height": parent.width / 2})
}
}
}
Component {
id: selectionComponent
Rectangle {
id: selComp
border {
width: 2
color: "steelblue"
}
color: "#354682B4"
property int rulersSize: 18
MouseArea { // drag mouse area
anchors.fill: parent
drag{
target: parent
minimumX: 0
minimumY: 0
maximumX: parent.parent.width - parent.width
maximumY: parent.parent.height - parent.height
smoothed: true
}
onDoubleClicked: {
parent.destroy() // destroy component
}
}
Rectangle {
width: rulersSize
height: rulersSize
radius: rulersSize
color: "steelblue"
anchors.left: parent.left
anchors.top: parent.top
MouseArea {
anchors.fill: parent
drag{ target: parent; axis: Drag.XAxis }
onMouseXChanged: {
if(drag.active){
selComp.width = selComp.width - mouseX
selComp.height = selComp.height - mouseY
selComp.x = selComp.x + mouseX
selComp.y = selComp.y + mouseY
if(selComp.width < 30)
selComp.width = 30
}
}
}
}
Rectangle {
width: rulersSize
height: rulersSize
radius: rulersSize
color: "steelblue"
anchors.left: parent.left
anchors.bottom: parent.bottom
MouseArea {
anchors.fill: parent
drag{ target: parent; axis: Drag.XAxis }
onMouseXChanged: {
if(drag.active){
selComp.width = selComp.width - mouseX
selComp.height = selComp.height + mouseY
//selComp.x = selComp.x + mouseX
//selComp.y = selComp.y + mouseY
if(selComp.width < 30)
selComp.width = 30
}
}
}
}
Rectangle {
width: rulersSize
height: rulersSize
radius: rulersSize
color: "steelblue"
anchors.horizontalCenter: parent.left
anchors.verticalCenter: parent.verticalCenter
MouseArea {
anchors.fill: parent
drag{ target: parent; axis: Drag.XAxis }
onMouseXChanged: {
if(drag.active){
selComp.width = selComp.width - mouseX
selComp.x = selComp.x + mouseX
if(selComp.width < 30)
selComp.width = 30
}
}
}
}
Rectangle {
width: rulersSize
height: rulersSize
radius: rulersSize
color: "steelblue"
anchors.horizontalCenter: parent.right
anchors.verticalCenter: parent.verticalCenter
MouseArea {
anchors.fill: parent
drag{ target: parent; axis: Drag.XAxis }
onMouseXChanged: {
if(drag.active){
selComp.width = selComp.width + mouseX
if(selComp.width < 50)
selComp.width = 50
}
}
}
}
Rectangle {
width: rulersSize
height: rulersSize
radius: rulersSize
x: parent.x / 2
y: 0
color: "steelblue"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.top
MouseArea {
anchors.fill: parent
drag{ target: parent; axis: Drag.YAxis }
onMouseYChanged: {
if(drag.active){
selComp.height = selComp.height - mouseY
selComp.y = selComp.y + mouseY
if(selComp.height < 50)
selComp.height = 50
}
}
}
}
Rectangle {
width: rulersSize
height: rulersSize
radius: rulersSize
x: parent.x / 2
y: parent.y
color: "steelblue"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.bottom
MouseArea {
anchors.fill: parent
drag{ target: parent; axis: Drag.YAxis }
onMouseYChanged: {
if(drag.active){
selComp.height = selComp.height + mouseY
if(selComp.height < 50)
selComp.height = 50
}
}
}
}
}
}
This will work:
Point.qml
import QtQuick 2.0
Item {
id: root
signal dragged()
Rectangle {
anchors.centerIn: parent
width: 20
height: 20
color: "blue"
opacity: 0.3
MouseArea {
anchors.fill: parent
drag.target: root
onPositionChanged: {
if(drag.active) {
dragged()
}
}
}
}
}
main.qml:
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 600
height: 600
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()
}
}
}
}