英文:
Multiple Marker with different Images as Icons in QML Map Widget
问题
我想要什么?
我在QML中有一个小部件,显示带有OSM插件的地图。在这张地图上,无论我在哪里点击,我都想放置一个标记。如果我在另一个位置点击,应该添加一个新的标记。在顶部,我有一个选项卡栏。根据按钮(currentIndex)的不同,应该在地图上点击时显示不同类型的图像/标记图标(目前为了测试在第一个选项卡上是蓝色矩形,在第二个选项卡上是红色圆圈)。所有标记应该保持在地图上可见。
当前代码:
导入 QtQuick 2.11
导入 QtPositioning 5.11
导入 QtLocation 5.11
导入 QtQuick.Controls 2.0
导入 QtQuick.Layouts 1.3
导入 QtQuick.Controls.Styles 1.4
矩形 {
id: 矩形
宽度: 640
高度: 480
插件 {
id: osmPlugin
名称: "osm"
PluginParameter{
name: "osm.mapping.providersrepository.address"
value: "http://127.0.0.1:8080/"
}
}
属性 variant locationTC: QtPositioning.coordinate(52.5200, 13.4050)
ListModel {
id: markermodel
dynamicRoles: true
}
装载器{
id: mloader
sourceComponent:
if(bar.currentIndex == 0)//some condition
return idRect
else if(bar.currentIndex == 1) //another condition
return idCircle
}
Component{
id: idRect
矩形{
宽度: 20
高度: 20
颜色: "blue"
}
}
Component{
id: idCircle
矩形{
颜色: "red"
宽度: 20
高度: 20
半径: 50
}
}
地图 {
id: map
anchors.fill: parent
plugin: osmPlugin
center: QtPositioning.coordinate(59.91, 10.75)
zoomLevel: 3
地图项目视图{
model: markermodel
delegate: MapQuickItem {
id: marker
coordinate: model.position_marker
sourceItem: model.marker_source
}
}
鼠标区域
{
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))
}
}
项目 {
标签栏 {
id: bar
宽度: 500
高度:25
背景: 矩形{
不透明度:0
}
重复器 {
model: ["C1", "C2", "C3", "C4", "C5"]
TabButton {
文本: modelData
宽度: 100
属性 int roundedEdge: 0 // 0 - no rounded edges, 1 - left side rounded, 2 - right side rounded
背景: 项目
{
矩形 {
id: 圆角矩形
高度: 25
宽度: 100
半径: roundedEdge == 0 ? 0 : 5
颜色: "#35383b"
}
矩形 {
id: 左方矩形
visible: roundedEdge == 2
颜色: "#35383b"
高度: 圆角矩形.height
宽度: 圆角矩形.width - 圆角矩形.radius
锚定.bottom: 圆角矩形.bottom
锚定.left: 圆角矩形.left
}
矩形 {
id: 右方矩形
visible: roundedEdge == 1
颜色: "#35383b"
高度: 圆角矩形.height
宽度: 圆角矩形.width - 圆角矩形.radius
锚定.bottom: 圆角矩形.bottom
锚定.right: 圆角矩形.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)
}
}
}
}
}
英文:
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 ?
答案1
得分: 1
你应该为每个委托(MapQuickItem
)创建一个新组件,而不是重用单个实例(mloader.item
).
所以做如下修改,移除mloader
和"marker_source"
角色:
...
矩形 {
...
地图 {
...
地图项目视图 {
模型: markermodel
代表: 地图快速项目 {
id: marker
坐标: 模型.position_marker
源项目: 装载器 {
源组件: [idRect, idCircle][模型.type]
}
}
}
鼠标区域 {
...
点击时: {
var coord = map.toCoordinate(Qt.point(mouse.x, mouse.y));
markermodel.append({"position_marker": coord, "type": bar.currentIndex})
...
}
}
}
...
}
...
英文:
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})
...
}
}
}
...
}
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论