QML.如何从C更改MapPolyline路径?

这是一张QML地图:

Map {
        anchors.fill: parent
        plugin: osmMapPlugin
        center: QtPositioning.coordinate(56.006355, 92.860984)
        zoomLevel: 14

        MapPolyline {
            line.width: 3
            line.color: 'red'
            path: [
                { latitude: -27, longitude: 153.0 },
                { latitude: -27, longitude: 154.1 },
                { latitude: -28, longitude: 153.5 },
                { latitude: -29, longitude: 153.5 }
            ]
        }
    }

如何从C / qt改变路径?我试过这个:

QML:

Map {
        anchors.fill: parent
        plugin: osmMapPlugin
        center: QtPositioning.coordinate(56.006355, 92.860984)
        zoomLevel: 14

        MapPolyline {
            line.width: 3
            line.color: 'red'

            path: map_path
        }
    }

C :

map = new QQuickWidget();
map->setSource(QUrl("qrc:map.qml"));

QQmlContext *qml_map = map->rootContext();
QGeoPath *path = new QGeoPath();
path->addCoordinate(*(new QGeoCoordinate(56.0831528053, 92.8405031454)));
path->addCoordinate(*(new QGeoCoordinate(56.1, 93)));
qml_map->setContextProperty("map_path", path);

但我有一个例外:

calling a private constructor of class 'QVariant':
    qml_map->setContextProperty("map_path", path);

attempted to use of deleted function:
    qml_map->setContextProperty("map_path", path);

UPD:
@ hi-im-frogatto建议有必要这样做:

qml_map->setContextProperty("map_path", QVariant::fromValue(path));

它有所帮助,错误不再发生.但是没有画出这条线.得到错误:

qrc:map.qml:30: ReferenceError: map_path is not defined
qrc:map.qml:21:5: QML Map: Plugin is a write-once property, and cannot be set again.

解决方法:

正如它说@HiI’mFrogatto你应该使用QVariant :: fromValue(),但它不能直接在.qml端使用:

QGeoPath geopath;
geopath.addCoordinate(QGeoCoordinate(56.006355, 92.860984));
geopath.addCoordinate(QGeoCoordinate(56.1, 93));
geopath.addCoordinate(QGeoCoordinate(56.1, 92.777));


QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("geopath", QVariant::fromValue(geopath));

你需要做的是通过循环访问每个元素:

Map {
    anchors.fill: parent
    plugin: osmMapPlugin
    center: QtPositioning.coordinate(56.006355, 92.860984)
    zoomLevel: 10

    MapPolyline {
        id: pl
        line.width: 3
        line.color: 'red'
    }

    Component.onCompleted: {
        var lines = []
        for(var i=0; i < geopath.size(); i++){
            lines[i] = geopath.coordinateAt(i)
        }
        pl.path = lines
    }
}

但是在这种情况下我们无法更新QGeoPath的值,因此可以实现一个继承自QObject并具有QGeoPath属性的类,因为您可以从C或QML中操作它.

main.cpp中

#include <QGeoPath>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QTimer>

class PathController: public QObject{
    Q_OBJECT
    Q_PROPERTY(QGeoPath geopath READ geoPath WRITE setGeoPath NOTIFY geopathChanged)
public:
    PathController(QObject *parent=0):QObject(parent){}
    void test(){
        mGeoPath.addCoordinate(QGeoCoordinate(56.006355, 92.860984));
        mGeoPath.addCoordinate(QGeoCoordinate(56.1, 93));
        mGeoPath.addCoordinate(QGeoCoordinate(56.1, 92.777));
        QTimer *timer = new QTimer(this);

        QObject::connect(timer, &QTimer::timeout, [this](){
            mGeoPath.translate(0.001, -0.01);
            emit geopathChanged();
        });
        timer->start(1000);

    }
    QGeoPath geoPath() const{return mGeoPath;}
    void setGeoPath(const QGeoPath &geoPath){
        if(geoPath == mGeoPath)
            return;
        mGeoPath = geoPath;
        emit geopathChanged();
    }

signals:
    void geopathChanged();
private:
    QGeoPath mGeoPath;
};

int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    PathController controller;
    controller.test();

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("pathController", &controller);

    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

import QtLocation 5.6
import QtPositioning 5.6

Window {
    visible: true
    width: 640
    height: 480

    Plugin {
        id: osmMapPlugin
        name: "osm"
    }

    Map {
        anchors.fill: parent
        plugin: osmMapPlugin
        center: QtPositioning.coordinate(56.006355, 92.860984)
        zoomLevel: 10

        MapPolyline {
            id: pl
            line.width: 10
            line.color: 'red'
        }
    }

    function loadPath(){
        var lines = []
        for(var i=0; i < pathController.geopath.size(); i++){
            lines[i] = pathController.geopath.coordinateAt(i)
        }
        return lines;
    }
    Connections{
        target: pathController
        onGeopathChanged: pl.path = loadPath()
    }

    Component.onCompleted: pl.path = loadPath()
}

在这个link中,您将找到完整的示例.

上一篇:c – 使用Qt3D 2.0的Billboarding


下一篇:02_基础语法巩固