qml mapToItem for quickmap item - qt
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
Related
How to make Rectangle behaves like a scrollbar 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" } } }
plus button under listview
I can create "+" (plus) button under all listview items. This button will add a new item. I can place it under all exsisting items. But ideály as a part as list.Because of scrolling, scrollbars and other standard listview functions. If listview will be not fill all available page size, scrolls will be ended in the middle of the screan etc... I tested counting onpaint signal or something like this, but have no success. Because signal for one row goint more than one times, counting is mismatched and button is one time in seccond row, one time below third, sometimes is missing etc... Example image: Source code: import QtQuick 2.10 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.2 import QtGraphicalEffects 1.0 Page { title: qsTr("Page 1") anchors.fill: parent focus: true property int myIndex: 0 function setVisibility() { if(myModel.rowCount()*3 === myIndex) { myIndex = 0 return true } else { myIndex = myIndex + 1 return false } } /* * * * ListView Component * * */ ListView { id: listView1 model: myModel currentIndex: 0 //property int actualHeight anchors.fill: parent clip: true //spacing: 40 highlightMoveDuration: 1 highlightMoveVelocity: 1 highlightResizeDuration: 0.0 highlight: Rectangle { color: "#2e6377" opacity: 0.3 } delegate: hDelegate } /* * * * ListViewItem Component * * */ Component { id: hDelegate Item { width: parent.width height: taskInfo.implicitHeight property variant mainData: model MouseArea { anchors.fill: parent onClicked: { listView1.currentIndex = index gIdd = listView1.currentItem.mainData.task_idd gSubject = listView1.currentItem.mainData.task_subject gBody = listView1.currentItem.mainData.task_body listView1.currentIndex = index } onDoubleClicked: { listView1.currentIndex = index stackView.push("page3.qml") } onPressAndHold: { listView1.currentIndex = index stackView.push("page3.qml") } hoverEnabled: true } Row { id: taskInfo spacing: 5 Rectangle { id: dificultStatus height: taskColumn.height width: taskColumn.height color: "transparent" Rectangle { id: rect22 color: "green" width: parent.width - 20 height: parent.height - 20 radius: 15 border.color: "lightsteelblue" border.width: 1 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } } Column { id: taskColumn width: listView1.width - editButton.width - dificultStatus.width - 10 Row { Text { text: task_subject color: "lightsteelblue" horizontalAlignment: Text.AlignRight wrapMode: Text.WordWrap font {family: localFont.name; pointSize: 14; letterSpacing: 1; wordSpacing: 1} } Text { text: task_subject color: "lightsteelblue" wrapMode: Text.WordWrap font {family: localFont.name; pointSize: 14; letterSpacing: 1; wordSpacing: 1} } } Text { id: text1 height: 50 width: parent.width clip: true text: task_body color: "lightsteelblue" wrapMode: Text.WordWrap font {family: localFont.name; pointSize: 14; letterSpacing: 1; wordSpacing: 1} } } Button { id: editButton height: taskColumn.height width: taskColumn.height background: Rectangle { anchors.fill: parent color: "transparent" Rectangle { color: "transparent" width: parent.width - 20 height: parent.height - 20 radius: 15 border.color: "lightsteelblue" border.width: 1 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } } Text { anchors.fill: parent text: qsTr("...") color: "lightsteelblue" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pixelSize: 24 anchors.centerIn: parent } onClicked: { listView1.currentIndex = index gIdd = listView1.currentItem.mainData.task_idd gSubject = listView1.currentItem.mainData.task_subject gBody = listView1.currentItem.mainData.task_body listView1.currentIndex = index stackView.push("page3.qml") } } /* * * * AddButton Component * * */ Button { height: taskColumn.height width: taskColumn.height x: 0 y: 80 visible: setVisibility() //visible: (myModel.rowCount() === ++myIndex) ? true : false background: Rectangle { anchors.fill: parent color: "transparent" Rectangle { color: "transparent" width: parent.width - 20 height: parent.height - 20 radius: 15 border.color: "lightsteelblue" border.width: 1 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } } Text { anchors.fill: parent text: qsTr("+") color: "lightsteelblue" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pixelSize: 24 anchors.centerIn: parent } onClicked: { listView1.currentIndex = index gIdd = listView1.currentItem.mainData.task_idd gSubject = listView1.currentItem.mainData.task_subject gBody = listView1.currentItem.mainData.task_body listView1.currentIndex = index stackView.push("page2.qml") } } } } } }
You can just use ListView's footer property. The default footerPositioning is what you want.
Drag coordinates of a QML shape
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() } } } }
How to move/animate components created by repeater in QML?
I have a component named Tile in Tile.qml, which I want to create by a Repeater. Tile.qml is as follows: import QtQuick 2.0 Rectangle { id: tile property string tileLabel: label.text property int tileSize: height width: 50 height: tileSize color: "green" border.color: Qt.lighter(color) anchors.bottom: parent.bottom Text { id: label color: "white"; anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.bottom text: tileLabel } } And my main.qml is as follows: import QtQuick 2.0 Rectangle { id: root width: 552; height: 300 color: "#3C3C3C" border.color: Qt.lighter(color) Row { id: tilesRow anchors.margins: 8 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter spacing: 4 Repeater { id: repeater model: 10 delegate: Tile { tileSize: Math.random() * 100 + 1 tileLabel: tileSize } } } Rectangle { id: button width: 100 height: 30 color: "gray" focus: true Text { anchors.centerIn: parent color: "white" text: "Button" } MouseArea { hoverEnabled: true anchors.fill: parent onEntered: { button.color = Qt.lighter("blue")} onExited: { button.color = "gray" } onPressed: { button.color = "blue" } onReleased: { button.color = Qt.lighter("blue") } onClicked: func() } } } I need to sort the tiles when the button is clicked so that the tiles are in ascending order by their labels. I can access the labels of the tiles using repeater.itemAt(i).tileSize. How can I animate the movement of tiles as they are moved/swapped?
Small example: import QtQuick 2.3 import QtQuick.Window 2.2 Window { visible: true width: 800 height: 600 Row { anchors.centerIn: parent property var word: ['H','e','l','l','o','!'] id: row Repeater { id: repeater model: row.word.length delegate: Rectangle { id: delegate; width: 100 height: 100 property int pos color: Qt.rgba(Math.random(),Math.random(),Math.random(),1); Text { anchors.centerIn: parent font.pixelSize: 36 color: "white" text: row.word[index] } Behavior on x { ParallelAnimation { PropertyAnimation { duration: 500 easing.type: Easing.InOutBack } SequentialAnimation { PropertyAnimation { target: delegate property: "y" from: 0 to: delegate.pos == 1 ? 20 : -20 duration: 250 } PropertyAnimation { target: delegate property: "y" from: delegate.pos == 1 ? 20 : -20 to: 0 duration: 250 } } } } Behavior on rotation { RotationAnimation { direction: RotationAnimation.Clockwise duration: 300 } } } } } Timer { interval: 1000 running: true repeat: true onTriggered: { var element1 = repeater.itemAt(Math.round(Math.random() * (repeater.count - 1))); var element2 = repeater.itemAt(Math.round(Math.random() * (repeater.count - 1))); if(element1 === element2) { element1.rotation = element1.rotation + 90; } else { element1.pos = 1; element2.pos = 2; var temp = element1.x; element1.x = element2.x; element2.x = temp; } } } }
QML : Drop-down menu that opens upward
I need to have drop-down that opens upwards on clicking on Menu button in QML. I have tried to use the listview for the same, but in the implementation we are getting drop-down which opens downwards. Any suggestions with reference to below snippet. import QtQuick 1.1 Rectangle { width: 800 height: 480 Rectangle { id:comboBox property variant items: ["Red", "Blue", "Green"] signal comboClicked; x: 651 y: 344 width: 141 height: 30; z: 0 smooth:true; Rectangle { id:chosenItem radius:4; width:parent.width; height:comboBox.height; color: "#454b4d" smooth:true; Text { anchors.top: parent.top; anchors.margins: 8; id:chosenItemText x: 11 y: 5 color: "#ffffff" text:"Menu"; anchors.topMargin: 5 anchors.left: parent.left anchors.leftMargin: 12 font.family: "Arial" font.pointSize: 14; smooth:true } MouseArea { width: 400 height: 30 anchors.bottomMargin: 0 anchors.fill: parent; onClicked: { comboBox.state = comboBox.state==="dropDown"?"":"dropDown" } } } Rectangle { id:dropDown width:comboBox.width; height:0; clip:true; radius:4; anchors.top: chosenItem.bottom; anchors.margins: 2; color: "lightblue" ListView { id:listView height:500; model: comboBox.items currentIndex: 0 delegate: Item{ width:comboBox.width; height: comboBox.height; Text { text: modelData anchors.top: parent.top; anchors.left: parent.left; anchors.margins: 5; } MouseArea { anchors.fill: parent; onClicked: { comboBox.state = "" chosenItemText.text = modelData; listView.currentIndex = index; } } } } } states: State { name: "dropDown"; PropertyChanges { target: dropDown; height:30*comboBox.items.length } } transitions: Transition { NumberAnimation { target: dropDown; properties: "height"; easing.type: Easing.OutExpo; duration: 1000 } } } }
Try to change the anchors of the dropDown item: that anchors.top: chosenItem.bottom; should become anchors.bottom: chosenItem.top;