QML.如何从 C++ 更改 MapPolyline 路径? [英] QML. How to change MapPolyline path from C++?

查看:23
本文介绍了QML.如何从 C++ 更改 MapPolyline 路径?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一张 QML 地图:

Here is a QML map:

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 更改 path?我试过这个:

How to change path from C++/qt? I tried this:

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);

统一更新:@hi-im-frogatto 建议有必要这样做:

UPD: @hi-im-frogatto suggested that it was necessary to do so:

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

它有帮助,错误不再发生.但是没有画线.出现错误:

It helped, the error no longer occurs. But the line is not drawn. Got error:

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端使用:

As it says @HiI'mFrogatto you should use QVariant::fromValue(), but it can not be used directly on the .qml side:

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));

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

what you have to do is access each element through a loop:

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 操作它.


But with this case we can not update the values of the QGeoPath, it is appropriate to implement a class that inherits from QObject and has as property to QGeoPath, since you can manipulate it from C++ or from QML.

ma​​in.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"

ma​​in.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()
}

在此 链接中,您将找到完整的示例.

In this link you will find the complete example.

这篇关于QML.如何从 C++ 更改 MapPolyline 路径?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆