Читайте C++ QVector структур в QML
В моем классе C++ у меня есть
struct trackPoint {
QString lat;
QString lon;
QString elevation;
};
QVector<trackPoint> trackPoints;
В QML я хочу получить доступ к этому как многомерный массив пар lon,lat
[[0,1],[1,1],[2,1]]
Возможно ли это с помощью механизма Q_Property? Как я уверен, что структуры не могут быть подвержены QML?
Я связал:-
Q_PROPERTY(QVector<trackPoint> trackPoints READ gpx)
С помощью метода:-
QVector<trackPoint> GPXFileIO::gpx() const {
return trackPoints;
}
Но это дает мне ошибку:
QMetaProperty::read: Unable to handle unregistered datatype 'QVector<trackPoint>' for property 'GPXFileIO::trackPoints'
2 ответа
Не добавляя сложности гаджетов, я нахожу довольно простым использование QVariantList из QVariantMap в качестве Qvariant. Вот как я это делаю:
Q_PROPERTY(QVariant trackpoints READ gpx NOTIFY gpxChanged)
QVariant TrackClass::gpx() const
{
QVariantList itemsList;
for(const TrackPoint &p : trackPoints)
{
QVariantMap itemMap;
itemMap.insert("lat", p.lat);
itemMap.insert("lon", p.lon);
itemMap.insert("elevation", p.elevation);
itemsList.append(itemMap);
}
return QVariant::fromValue(itemsList);
}
Затем в QML вы можете использовать трекпоинты в качестве модели и получать доступ к полям элемента по имени. Рекомендуется также добавить сигнал NOTIFY, который будет вызываться при изменении вашего QVector.
Простой способ представить структуру в QML - использовать Q_GADGET с Q_PROPERTY, чтобы мы могли получить каждый элемент структуры, они не будут частью массива. С другой стороны, QVector поддерживает ряд элементов с QString, int, QUrl и т. Д., Но не для новых типов, и в этом случае следует использовать QVariantList.
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QVector>
struct TrackPoint {
Q_GADGET
Q_PROPERTY(qreal lat MEMBER lat)
Q_PROPERTY(qreal lon MEMBER lon)
Q_PROPERTY(qreal elevation MEMBER elevation)
public:
qreal lat;
qreal lon;
qreal elevation;
};
class TrackClass: public QObject
{
Q_OBJECT
Q_PROPERTY(QVariantList trackpoints READ gpx)
public:
TrackClass(QObject *parent=nullptr):QObject(parent){
trackPoints << TrackPoint{10, 10, 10} << TrackPoint{11, 11, 11};
}
QVariantList gpx() const{
QVariantList l;
for(const TrackPoint & p: trackPoints){
l << QVariant::fromValue(p);
}
return l;
}
private:
QVector<TrackPoint> trackPoints;
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
TrackClass track;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("track", &track);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
#include "main.moc"
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Component.onCompleted: {
for( var i in track.trackpoints){
var p = track.trackpoints[i];
console.log("lat: ", p.lat, "lon: ", p.lon, "elevation: ", p.elevation)
}
}
}
Выход:
qml: lat: 10 lon: 10 elevation: 10
qml: lat: 11 lon: 11 elevation: 11