Читайте C ++ QVector структур в QML - PullRequest
0 голосов
/ 14 октября 2018

В моем классе 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 ]

0 голосов
/ 15 октября 2018

Не добавляя сложности гаджетов, я нахожу довольно простым использование 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.

0 голосов
/ 15 октября 2018

Простой способ представить структуру в 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
...