在QML地图小部件中使用不同图像作为标记的多个标记。

huangapple go评论106阅读模式
英文:

Multiple Marker with different Images as Icons in QML Map Widget

问题

我想要什么?
我在QML中有一个小部件,显示带有OSM插件的地图。在这张地图上,无论我在哪里点击,我都想放置一个标记。如果我在另一个位置点击,应该添加一个新的标记。在顶部,我有一个选项卡栏。根据按钮(currentIndex)的不同,应该在地图上点击时显示不同类型的图像/标记图标(目前为了测试在第一个选项卡上是蓝色矩形,在第二个选项卡上是红色圆圈)。所有标记应该保持在地图上可见。

当前代码:

  1. 导入 QtQuick 2.11
  2. 导入 QtPositioning 5.11
  3. 导入 QtLocation 5.11
  4. 导入 QtQuick.Controls 2.0
  5. 导入 QtQuick.Layouts 1.3
  6. 导入 QtQuick.Controls.Styles 1.4
  7. 矩形 {
  8. id: 矩形
  9. 宽度: 640
  10. 高度: 480
  11. 插件 {
  12. id: osmPlugin
  13. 名称: "osm"
  14. PluginParameter{
  15. name: "osm.mapping.providersrepository.address"
  16. value: "http://127.0.0.1:8080/"
  17. }
  18. }
  19. 属性 variant locationTC: QtPositioning.coordinate(52.5200, 13.4050)
  20. ListModel {
  21. id: markermodel
  22. dynamicRoles: true
  23. }
  24. 装载器{
  25. id: mloader
  26. sourceComponent:
  27. if(bar.currentIndex == 0)//some condition
  28. return idRect
  29. else if(bar.currentIndex == 1) //another condition
  30. return idCircle
  31. }
  32. Component{
  33. id: idRect
  34. 矩形{
  35. 宽度: 20
  36. 高度: 20
  37. 颜色: "blue"
  38. }
  39. }
  40. Component{
  41. id: idCircle
  42. 矩形{
  43. 颜色: "red"
  44. 宽度: 20
  45. 高度: 20
  46. 半径: 50
  47. }
  48. }
  49. 地图 {
  50. id: map
  51. anchors.fill: parent
  52. plugin: osmPlugin
  53. center: QtPositioning.coordinate(59.91, 10.75)
  54. zoomLevel: 3
  55. 地图项目视图{
  56. model: markermodel
  57. delegate: MapQuickItem {
  58. id: marker
  59. coordinate: model.position_marker
  60. sourceItem: model.marker_source
  61. }
  62. }
  63. 鼠标区域
  64. {
  65. id: mouseArea
  66. anchors.fill: parent
  67. hoverEnabled: true
  68. onClicked: {
  69. var coord = map.toCoordinate(Qt.point(mouse.x,mouse.y));
  70. var msource = mloader.item;
  71. markermodel.append({"position_marker": coord, "marker_source": msource})
  72. Hugo.getCoordinates((map.toCoordinate(Qt.point(mouse.x,mouse.y)).latitude), (map.toCoordinate(Qt.point(mouse.x,mouse.y)).longitude))
  73. }
  74. }
  75. 项目 {
  76. 标签栏 {
  77. id: bar
  78. 宽度: 500
  79. 高度:25
  80. 背景: 矩形{
  81. 不透明度:0
  82. }
  83. 重复器 {
  84. model: ["C1", "C2", "C3", "C4", "C5"]
  85. TabButton {
  86. 文本: modelData
  87. 宽度: 100
  88. 属性 int roundedEdge: 0 // 0 - no rounded edges, 1 - left side rounded, 2 - right side rounded
  89. 背景: 项目
  90. {
  91. 矩形 {
  92. id: 圆角矩形
  93. 高度: 25
  94. 宽度: 100
  95. 半径: roundedEdge == 0 ? 0 : 5
  96. 颜色: "#35383b"
  97. }
  98. 矩形 {
  99. id: 左方矩形
  100. visible: roundedEdge == 2
  101. 颜色: "#35383b"
  102. 高度: 圆角矩形.height
  103. 宽度: 圆角矩形.width - 圆角矩形.radius
  104. 锚定.bottom: 圆角矩形.bottom
  105. 锚定.left: 圆角矩形.left
  106. }
  107. 矩形 {
  108. id: 右方矩形
  109. visible: roundedEdge == 1
  110. 颜色: "#35383b"
  111. 高度: 圆角矩形.height
  112. 宽度: 圆角矩形.width - 圆角矩形.radius
  113. 锚定.bottom: 圆角矩形.bottom
  114. 锚定.right: 圆角矩形.right
  115. }
  116. }
  117. }
  118. }
  119. onCountChanged: {
  120. for(let i = 0; i < bar.count; i++)
  121. {
  122. if(i == 0)
  123. bar.itemAt(i).roundedEdge = 1
  124. else if(i == bar.count - 1)
  125. bar.itemAt(i).roundedEdge = 2
  126. else
  127. bar.itemAt(i).roundedEdge = 0
  128. }
  129. }
  130. onCurrentIndexChanged: {
  131. if(bar.currentIndex == 2)
  132. print("currentIndex changed to", currentIndex)
  133. }
  134. }
  135. }
  136. }
  137. }
英文:

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:

  1. import QtPositioning 5.11
  2. import QtLocation 5.11
  3. import QtQuick.Controls 2.0
  4. import QtQuick.Layouts 1.3
  5. import QtQuick.Controls.Styles 1.4
  6. Rectangle {
  7. id:rectangle
  8. width: 640
  9. height: 480
  10. Plugin {
  11. id: osmPlugin
  12. name: &quot;osm&quot;
  13. PluginParameter{
  14. name:&quot;osm.mapping.providersrepository.address&quot;
  15. value: &quot;http://127.0.0.1:8080/&quot;
  16. }
  17. }
  18. property variant locationTC: QtPositioning.coordinate(52.5200, 13.4050)
  19. ListModel {
  20. id: markermodel
  21. dynamicRoles: true
  22. }
  23. Loader{
  24. id: mloader
  25. sourceComponent:
  26. if(bar.currentIndex == 0)//some condition
  27. return idRect
  28. else if(bar.currentIndex == 1) //another condition
  29. return idCircle
  30. }
  31. Component{
  32. id: idRect
  33. Rectangle{
  34. width: 20
  35. height: 20
  36. color: &quot;blue&quot;
  37. }
  38. }
  39. Component{
  40. id: idCircle
  41. Rectangle{
  42. color: &quot;red&quot;
  43. width: 20
  44. height: 20
  45. radius: 50
  46. }
  47. }
  48. Map {
  49. id: map
  50. anchors.fill: parent
  51. plugin: osmPlugin
  52. center: QtPositioning.coordinate(59.91, 10.75)
  53. zoomLevel: 3
  54. MapItemView{
  55. model: markermodel
  56. delegate: MapQuickItem {
  57. id: marker
  58. coordinate: model.position_marker
  59. sourceItem: model.marker_source
  60. }
  61. }
  62. MouseArea
  63. {
  64. id: mouseArea
  65. anchors.fill: parent
  66. hoverEnabled: true
  67. onClicked: {
  68. var coord = map.toCoordinate(Qt.point(mouse.x,mouse.y));
  69. var msource = mloader.item;
  70. markermodel.append({&quot;position_marker&quot;: coord, &quot;marker_source&quot;: msource})
  71. Hugo.getCoordinates((map.toCoordinate(Qt.point(mouse.x,mouse.y)).latitude), (map.toCoordinate(Qt.point(mouse.x,mouse.y)).longitude))
  72. }
  73. }
  74. Item {
  75. TabBar {
  76. id: bar
  77. width: 500
  78. height:25
  79. background: Rectangle{
  80. opacity:0
  81. }
  82. Repeater {
  83. model: [qsTr(&quot;C1&quot;), qsTr(&quot;C2&quot;), qsTr(&quot;C3&quot;), qsTr(&quot;C4&quot;), qsTr(&quot;C5&quot;)]
  84. TabButton {
  85. text: modelData
  86. width: 100
  87. property int roundedEdge: 0 // 0 - no rounded edges, 1 - left side rounded, 2 - right side rounded
  88. background: Item
  89. {
  90. Rectangle {
  91. id: roundRect
  92. height: 25
  93. width: 100
  94. radius: roundedEdge == 0 ? 0 : 5
  95. color: &quot;#35383b&quot;
  96. }
  97. Rectangle {
  98. id: leftSquareRect
  99. visible: roundedEdge == 2
  100. color: &quot;#35383b&quot;
  101. height: roundRect.height
  102. width: roundRect.width - roundRect.radius
  103. anchors.bottom : roundRect.bottom
  104. anchors.left : roundRect.left
  105. }
  106. Rectangle {
  107. id: rightSquareRect
  108. visible: roundedEdge == 1
  109. color: &quot;#35383b&quot;
  110. height: roundRect.height
  111. width: roundRect.width - roundRect.radius
  112. anchors.bottom : roundRect.bottom
  113. anchors.right : roundRect.right
  114. }
  115. }
  116. }
  117. }
  118. onCountChanged: {
  119. for(let i = 0; i &lt; bar.count; i++)
  120. {
  121. if(i == 0)
  122. bar.itemAt(i).roundedEdge = 1
  123. else if(i == bar.count - 1)
  124. bar.itemAt(i).roundedEdge = 2
  125. else
  126. bar.itemAt(i).roundedEdge = 0
  127. }
  128. }
  129. onCurrentIndexChanged: {
  130. if(bar.currentIndex == 2)
  131. print(&quot;currentIndex changed to&quot;, currentIndex)
  132. }
  133. }
  134. }
  135. }
  136. }

.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&quot;marker_source&quot;角色:

  1. ...
  2. 矩形 {
  3. ...
  4. 地图 {
  5. ...
  6. 地图项目视图 {
  7. 模型: markermodel
  8. 代表: 地图快速项目 {
  9. id: marker
  10. 坐标: 模型.position_marker
  11. 源项目: 装载器 {
  12. 源组件: [idRect, idCircle][模型.type]
  13. }
  14. }
  15. }
  16. 鼠标区域 {
  17. ...
  18. 点击时: {
  19. var coord = map.toCoordinate(Qt.point(mouse.x, mouse.y));
  20. markermodel.append({&quot;position_marker&quot;: coord, &quot;type&quot;: bar.currentIndex})
  21. ...
  22. }
  23. }
  24. }
  25. ...
  26. }
  27. ...
英文:

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 &quot;marker_source&quot; role.

  1. ...
  2. Rectangle {
  3. ...
  4. Map {
  5. ...
  6. MapItemView {
  7. model: markermodel
  8. delegate: MapQuickItem {
  9. id: marker
  10. coordinate: model.position_marker
  11. sourceItem: Loader {
  12. sourceComponent: [idRect, idCircle][model.type]
  13. }
  14. }
  15. }
  16. MouseArea
  17. {
  18. ...
  19. onClicked: {
  20. var coord = map.toCoordinate(Qt.point(mouse.x, mouse.y));
  21. markermodel.append({&quot;position_marker&quot;: coord, &quot;type&quot;: bar.currentIndex})
  22. ...
  23. }
  24. }
  25. }
  26. ...
  27. }
  28. ...

huangapple
  • 本文由 发表于 2023年6月29日 22:00:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76581766.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定