读C++;QML中结构的QVector 我的C++类中有< /p> struct trackPoint { QString lat; QString lon; QString elevation; }; QVector<trackPoint> trackPoints;

读C++;QML中结构的QVector 我的C++类中有< /p> struct trackPoint { QString lat; QString lon; QString elevation; }; QVector<trackPoint> trackPoints;,c++,qt,qml,qt5,qproperty,C++,Qt,Qml,Qt5,Qproperty,这是否可能使用Q_属性机制?因为我很确定结构不能暴露于QML 我打成平局:- Q_PROPERTY(QVector<trackPoint> trackPoints READ gpx) Q_属性(QVector轨迹点读取gpx) 用一种方法:- QVector<trackPoint> GPXFileIO::gpx() const { return trackPoints; } QVector GPXFileIO::gpx()常量{ 返回轨迹点; } 但这给了我一

这是否可能使用Q_属性机制?因为我很确定结构不能暴露于QML

我打成平局:-

 Q_PROPERTY(QVector<trackPoint> trackPoints READ gpx)
Q_属性(QVector轨迹点读取gpx)
用一种方法:-

QVector<trackPoint> GPXFileIO::gpx() const {
 return trackPoints;
}
QVector GPXFileIO::gpx()常量{
返回轨迹点;
}
但这给了我一个错误:-

QMetaProperty::read: Unable to handle unregistered datatype 'QVector<trackPoint>' for property 'GPXFileIO::trackPoints'
QMetaProperty::read:无法处理属性“GPXFileIO::trackPoints”的未注册数据类型“QVector”

向QML公开结构的一种简单方法是使用具有Q_属性的Q_GADGET,这样我们就可以获得结构的每个元素,它们不会是数组的一部分。另一方面,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"
输出:

qml: lat:  10 lon:  10 elevation:  10
qml: lat:  11 lon:  11 elevation:  11

在不增加小工具复杂性的情况下,我发现QVariantMap的QVariantList作为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中,您可以使用轨迹点作为模型,并按名称访问项字段。 一个很好的做法是添加一个通知信号,在QVector发生变化时调用

qml: lat:  10 lon:  10 elevation:  10
qml: lat:  11 lon:  11 elevation:  11
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);
}