What do I want ? I have a widget in QML which displays a map with OSM plugin. On this map whenever I click I want to place a marker. If I click on another position a new marker should be added. In the top I have a Tabbar. Depending on which Button (currentIndex) a different type of Image/Marker Icon should be displayed with the click on the map (currently for test reasons on the first tab blue rectangles on the second red circles). And all markers should stay visible on the map.
Current Code:
import QtPositioning 5.11
import QtLocation 5.11
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.4
Rectangle {
id:rectangle
width: 640
height: 480
Plugin {
id: osmPlugin
name: "osm"
PluginParameter{
name:"osm.mapping.providersrepository.address"
value: "http://127.0.0.1:8080/"
}
}
property variant locationTC: QtPositioning.coordinate(52.5200, 13.4050)
ListModel {
id: markermodel
dynamicRoles: true
}
Loader{
id: mloader
sourceComponent:
if(bar.currentIndex == 0)//some condition
return idRect
else if(bar.currentIndex == 1) //another condition
return idCircle
}
Component{
id: idRect
Rectangle{
width: 20
height: 20
color: "blue"
}
}
Component{
id: idCircle
Rectangle{
color: "red"
width: 20
height: 20
radius: 50
}
}
Map {
id: map
anchors.fill: parent
plugin: osmPlugin
center: QtPositioning.coordinate(59.91, 10.75)
zoomLevel: 3
MapItemView{
model: markermodel
delegate: MapQuickItem {
id: marker
coordinate: model.position_marker
sourceItem: model.marker_source
}
}
MouseArea
{
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
var coord = map.toCoordinate(Qt.point(mouse.x,mouse.y));
var msource = mloader.item;
markermodel.append({"position_marker": coord, "marker_source": msource})
Hugo.getCoordinates((map.toCoordinate(Qt.point(mouse.x,mouse.y)).latitude), (map.toCoordinate(Qt.point(mouse.x,mouse.y)).longitude))
}
}
Item {
TabBar {
id: bar
width: 500
height:25
background: Rectangle{
opacity:0
}
Repeater {
model: [qsTr("C1"), qsTr("C2"), qsTr("C3"), qsTr("C4"), qsTr("C5")]
TabButton {
text: modelData
width: 100
property int roundedEdge: 0 // 0 - no rounded edges, 1 - left side rounded, 2 - right side rounded
background: Item
{
Rectangle {
id: roundRect
height: 25
width: 100
radius: roundedEdge == 0 ? 0 : 5
color: "#35383b"
}
Rectangle {
id: leftSquareRect
visible: roundedEdge == 2
color: "#35383b"
height: roundRect.height
width: roundRect.width - roundRect.radius
anchors.bottom : roundRect.bottom
anchors.left : roundRect.left
}
Rectangle {
id: rightSquareRect
visible: roundedEdge == 1
color: "#35383b"
height: roundRect.height
width: roundRect.width - roundRect.radius
anchors.bottom : roundRect.bottom
anchors.right : roundRect.right
}
}
}
}
onCountChanged: {
for(let i = 0; i < bar.count; i++)
{
if(i == 0)
bar.itemAt(i).roundedEdge = 1
else if(i == bar.count - 1)
bar.itemAt(i).roundedEdge = 2
else
bar.itemAt(i).roundedEdge = 0
}
}
onCurrentIndexChanged: {
if(bar.currentIndex == 2)
print("currentIndex changed to", currentIndex)
}
}
}
}
}
.getCoordinates is a Signal to a Python backend.
I tried to realise the above desired functionality in the MouseArea.onClicked event. However in the current implementation only the switching of the marker icons work but only the latest marker remains.
Moving the loader definition to the MapQuickItem.sourceItem definition results in the following. The markers remain but changing the tab index switches the icon for all marker new and old.
What am I doing wrong and how can I achieve the desired functionality ? Moreover do i have a misconception on the interactions ?
You should create a new component for each delegate(MapQuickItem
), instead of reusing a single instance(the mloader.item
).
So do like this, removing the mloader
and the "marker_source"
role.
...
Rectangle {
...
Map {
...
MapItemView {
model: markermodel
delegate: MapQuickItem {
id: marker
coordinate: model.position_marker
sourceItem: Loader {
sourceComponent: [idRect, idCircle][model.type]
}
}
}
MouseArea
{
...
onClicked: {
var coord = map.toCoordinate(Qt.point(mouse.x, mouse.y));
markermodel.append({"position_marker": coord, "type": bar.currentIndex})
...
}
}
}
...
}
...