В QML (как) я могу сделать MapItemGroup компонентом делегата MapItemView?
Ситуация: я могу использовать элемент карты QML с моделью / представлением / делегатом. Я умею работать с отдельными предметами.
Задача: в качестве следующего шага я хотел бы иметь возможность рисовать несколько элементов. Мне нужно поставить несколько QML MapItems (например, MapCircle, MapRectangle и др..) в одном компоненте делегата. Как правило, QML поддерживает несколько элементов внутри делегата. Проблема заключается в делегатеMapItemView : он не поддерживает несколько дочерних объектов предметы.
Мой Подход:
Я думал, что использование MapItemGroup будет работать. Но мне кажется, что я чего-то не понимаю. Документация также не так обширна о том, как я могу заставить его работать в качестве компонента делегата. В прилагаемом фрагменте кода показана эта реализация.
Документация Qt по MapItemGroup
В приведенном ниже коде:
- delegateCircle, delegateRect прекрасно работают
- делегатегруппа-это не отображается
Простая реализация:
import QtQuick 2.10
import QtPositioning 5.6
import QtLocation 5.9
import QtQuick.Controls 2.3 as QQc2
QQc2.ApplicationWindow {
visible: true
width: 640
height: 480
// Some list model
ListModel {
id: someModel
ListElement {lat: 0; lon: 0}
ListElement {lat: 5; lon: 0}
ListElement {lat: 5; lon: 5}
ListElement {lat: 0; lon: 5}
}
Map {
id: map
anchors.fill: parent
plugin: Plugin {name: "osm"}
center: QtPositioning.coordinate(2.5, 2.5)
zoomLevel: 6
// Some views to test the model
// delegateCircle, delegateRect work fine
// delegateGroup is not displayed
MapItemView {
model: someModel
delegate: MapCircle {
id: delegateCircle
border.color: "red"
border.width: 1
center: QtPositioning.coordinate(model.lat, model.lon)
radius: 50*1000
}
}
MapItemView {
model: someModel
delegate: MapRectangle {
id: delegateRect
border.color: "green"
border.width: 3
topLeft : QtPositioning.coordinate(model.lat+1, model.lon-1)
bottomRight : QtPositioning.coordinate(model.lat-1, model.lon+1)
}
}
MapItemView {
model: someModel
delegate: MapItemGroup {
id: delegateGroup
MapCircle {
id: innerCircle
border.color: "green"
border.width: 3
center: QtPositioning.coordinate(model.lat, model.lon)
radius: 75*1000
}
MapRectangle {
id: innerRect
border.color: "red"
border.width: 6
topLeft : QtPositioning.coordinate(model.lat+2, model.lon-2)
bottomRight : QtPositioning.coordinate(model.lat-2, model.lon+2)
}
}
}
}
}
Вывод указанного выше кода выглядит следующим образом::

- я также попытался использовать MapItemGroup в качестве sourceItem типа MapQuickItem. Это тоже не сработало.
Чего я хочу добиться:
Хорошо. Мне нужно нарисовать несколько элементов карты, используяMapItemView . Любое другое решение / метод (включая C++ backend программу) является добро пожаловать.
EDIT
Спасибо @GrecKo и @Yoann. Оба ваших решения работают. Однако я решил продолжить работу с Instantiator, поскольку он больше подходит для моего приложения.
Я также нашел это интересным после просмотра вашего решения: обсуждение разработчика о заполнении модели с помощью повторителя и Инстанциатора.
2 ответов:
К сожалению,
MapItemViewработает только сMapItem-производными элементами, иMapItemGroupне является одним из них.Вы можете использовать
Repeater, и он будет работать для делегатов, созданных с самого начала, но он не будет работать, если вы добавите строки в свою модель позже. Я объяснил в этот другой ответ, ПочемуRepeaterне очень хорошо подходит дляMap.В своем ответе я советую использовать
MapItemView, но здесь это неприменимо. Надеюсь, есть еще одно последнее доступное решение :Instantiatorс помощью карта.addMapItemGroup () и Map.removeMapItemGroup () .import QtQuick 2.10 import QtPositioning 5.6 import QtLocation 5.9 import QtQuick.Controls 2.3 as QQc2 import QtQml 2.2 QQc2.ApplicationWindow { visible: true width: 640 height: 480 ListModel { id: someModel ListElement {lat: 0; lon: 0} ListElement {lat: 5; lon: 0} ListElement {lat: 5; lon: 5} ListElement {lat: 0; lon: 5} } Timer { interval: 1000 running: true repeat: true property bool toggle: true onTriggered: { if (toggle) someModel.append({lat: 2.5, lon: 2.5}); else someModel.remove(4); toggle = !toggle; } } Map { id: map anchors.fill: parent plugin: Plugin {name: "osm"} center: QtPositioning.coordinate(2.5, 2.5) zoomLevel: 6 Instantiator { model: someModel delegate: MapItemGroup { id: delegateGroup MapCircle { id: innerCircle border.color: "green" border.width: 3 center: QtPositioning.coordinate(model.lat, model.lon) radius: 75*1000 } MapRectangle { id: innerRect border.color: "red" border.width: 6 topLeft : QtPositioning.coordinate(model.lat+2, model.lon-2) bottomRight : QtPositioning.coordinate(model.lat-2, model.lon+2) } } onObjectAdded: map.addMapItemGroup(object) onObjectRemoved: map.removeMapItemGroup(object) } } }
Вместо
MapItemView{[5] можно использовать простойRepeater]}import QtQuick 2.10 import QtPositioning 5.6 import QtLocation 5.9 import QtQuick.Controls 2.3 ApplicationWindow { visible: true width: 640 height: 480 // Some list model ListModel { id: someModel ListElement {lat: 0; lon: 0} ListElement {lat: 5; lon: 0} ListElement {lat: 5; lon: 5} ListElement {lat: 0; lon: 5} } Map { id: map anchors.fill: parent plugin: Plugin {name: "osm"} center: QtPositioning.coordinate(2.5, 2.5) zoomLevel: 6 Repeater { model: someModel MapItemGroup { id: delegateGroup MapCircle { id: innerCircle border.color: "green" border.width: 3 center: QtPositioning.coordinate(model.lat, model.lon) radius: 75*1000 } MapRectangle { id: innerRect border.color: "red" border.width: 6 topLeft : QtPositioning.coordinate(model.lat+2, model.lon-2) bottomRight : QtPositioning.coordinate(model.lat-2, model.lon+2) } Component.onCompleted: map.addMapItemGroup(this) } } } }Как указал греко, для того, чтобы это работало с динамической моделью, itemGroup должен быть" вручную " добавлен на карту, следовательно, линия
Component.onCompleted: map.addMapItemGroup(this)
Comments