Вместо экспорта маркера QML в C ++ лучше всего экспортировать QObject из C ++ в QML, и, поскольку вы хотите обрабатывать несколько маркеров, вы должны использовать модель.
Объяснениеподход:
Шаблон MVC - это естественный способ обработки большого количества информации в Qt, и для этого он реализует представления, такие как MapItemView, и модели, которые можно создавать на основе QAbstractXXXModel.Таким образом, только ответственность состоит в том, чтобы специализировать классы для цели, например, реализовать логику простого хранения n элементов и, если есть новый элемент, удалить самый старый.
Почему лучшеэкспортировать QObject в QML? Жизненный цикл объектов в QML обрабатывается QML, поэтому в вашем случае вы можете получить доступ к маркерам в данный момент времени, QML может удалить его, чтобы указатель в C ++ добавлял неЗарезервированная память.Другое преимущество состоит в том, что Q_PROPERTY распознается в QML, а тип данных известен в QML и C ++, в отличие от экспорта объекта QML в C ++, поскольку будут использоваться только свойства QObject или QQuickItem.Также при экспорте с использованием setContextProperty QObject является глобальным.Недостатком является то, что добавляется больше кода.Для получения более подробной информации читайте Взаимодействие с QML из C ++ .
markermodel.h
#ifndef MARKERMODEL_H
#define MARKERMODEL_H
#include <QAbstractListModel>
#include <QGeoCoordinate>
class MarkerModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(QGeoCoordinate current READ current NOTIFY currentChanged)
public:
enum MarkerRoles{
PositionRole = Qt::UserRole + 1000,
};
explicit MarkerModel(QObject *parent = nullptr);
void moveMarker(const QGeoCoordinate & coordinate);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
int maxMarkers() const;
void setMaxMarkers(int maxMarkers=0);
QGeoCoordinate current() const;
signals:
void currentChanged();
private:
void insert(int row, const QGeoCoordinate & coordinate);
void removeLastMarker();
QList<QGeoCoordinate> m_markers;
QGeoCoordinate m_current;
int m_maxMarkers;
};
#endif // MARKERMODEL_H
markermodel.cpp
#include "markermodel.h"
MarkerModel::MarkerModel(QObject *parent)
: QAbstractListModel(parent),
m_maxMarkers(0)
{
}
void MarkerModel::moveMarker(const QGeoCoordinate &coordinate)
{
QGeoCoordinate last = m_current;
m_current = coordinate;
Q_EMIT currentChanged();
if(!last.isValid())
return;
if(m_maxMarkers == 0){
insert(0, last);
return;
}
if(rowCount() >= m_maxMarkers){
while (rowCount() >= m_maxMarkers)
removeLastMarker();
removeLastMarker();
}
insert(0, last);
}
int MarkerModel::maxMarkers() const
{
return m_maxMarkers;
}
void MarkerModel::setMaxMarkers(int maxMarkers)
{
m_maxMarkers = maxMarkers > 1 ? maxMarkers: 0;
}
QGeoCoordinate MarkerModel::current() const
{
return m_current;
}
int MarkerModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return m_markers.count();
}
QVariant MarkerModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if(role == PositionRole)
return QVariant::fromValue(m_markers[index.row()]);
return QVariant();
}
QHash<int, QByteArray> MarkerModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[PositionRole] = "position";
return roles;
}
void MarkerModel::insert(int row, const QGeoCoordinate & coordinate)
{
beginInsertRows(QModelIndex(), row, row);
m_markers.insert(row, coordinate);
endInsertRows();
}
void MarkerModel::removeLastMarker()
{
if(m_markers.isEmpty())
return;
beginRemoveRows(QModelIndex(), rowCount()-1, rowCount()-1);
m_markers.removeLast();
endRemoveRows();
}
mainwindow.h
// ...
MarkerModel marker_model;
// ...
mainwindow.cpp
// ...
ui->quickWidget->rootContext()->setContextProperty("marker_model", &marker_model);
ui->quickWidget->setSource(QUrl("qrc:/mapview.qml"));
// ...
main.qml
// ...
Map{
id: map
anchors.fill: parent
plugin: mapPlugin
center: QtPositioning.coordinate(15.4561,73.8021);
zoomLevel: 14
Marker{
coordinate: marker_model.current
}
MapItemView{
model: marker_model
delegate: Marker{
coordinate: model.position
}
}
}
// ...
Полный пример: здесь