В QML (как) я могу сделать MapItemGroup компонентом делегата MapItemView?



Ситуация: я могу использовать элемент карты QML с моделью / представлением / делегатом. Я умею работать с отдельными предметами.



Задача: в качестве следующего шага я хотел бы иметь возможность рисовать несколько элементов. Мне нужно поставить несколько QML MapItems (например, MapCircle, MapRectangle и др..) в одном компоненте делегата. Как правило, QML поддерживает несколько элементов внутри делегата. Проблема заключается в делегатеMapItemView : он не поддерживает несколько дочерних объектов предметы.



Мой Подход:





  1. Я думал, что использование 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)
}
}
}
}
}


Вывод указанного выше кода выглядит следующим образом::
Вывод кода QML




  1. я также попытался использовать MapItemGroup в качестве sourceItem типа MapQuickItem. Это тоже не сработало.


Чего я хочу добиться:



Хорошо. Мне нужно нарисовать несколько элементов карты, используяMapItemView . Любое другое решение / метод (включая C++ backend программу) является добро пожаловать.



EDIT



Спасибо @GrecKo и @Yoann. Оба ваших решения работают. Однако я решил продолжить работу с Instantiator, поскольку он больше подходит для моего приложения.



Я также нашел это интересным после просмотра вашего решения: обсуждение разработчика о заполнении модели с помощью повторителя и Инстанциатора.

834   2  

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

    Ничего не найдено.