如何在QML QtLocation映射上添加来自C ++ Qt代码的PoI

时间:2016-06-22 19:16:20

标签: c++ qt dictionary qml

Qt noob在这里。我正在尝试使用Qt5开发一个桌面应用程序,该应用程序使用PoI gps坐标读取json并将其显​​示在地图上。 似乎能够轻松实现这一目标的唯一原生API是QtLocation,它显然只是QML。发现QML,我仍然设法在我的代码中集成一个地图,甚至直接添加到QML中的PoI,但我似乎无法在我的C ++代码中在地图上动态创建它们,我不知道还没真的得到QML。我尝试了各种方法,但没有取得任何进展,所以我怀疑我对这个问题的处理方法。

这是我到目前为止所做的:

main.cpp中:

#include "analyserq.h"
#include <QtWidgets/QApplication>
#include <QQuickView>
#include <QQuickItem>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    analyserQ w;

    w.show();
    return a.exec();
}

analyserq.h:

#ifndef ANALYSERQ_H

#define ANALYSERQ_H

#include <QtWidgets/QWidget>
#include <QtWidgets>
#include "ui_analyserq.h"
#include <QQuickView>
#include <QQuickItem>
#include <qqmlengine.h>

class analyserQ : public QWidget
{
    Q_OBJECT

public:
    analyserQ(QWidget *parent = 0);
    ~analyserQ();

private:
    Ui::analyserQClass ui;
    QPushButton *button;
private slots:

};

#endif // ANALYSERQ_H

analyserq.cpp:

#include "analyserq.h"

analyserQ::analyserQ(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    QQuickView *view = new QQuickView();
    QWidget *map = new QWidget();
    QWidget *container = QWidget::createWindowContainer(view, map);
    container->setMinimumSize(200, 200);
    container->setMaximumSize(200, 200);
    container->setFocusPolicy(Qt::TabFocus  );
    view->setSource(QUrl("map.qml"));
    button = new QPushButton(tr("&Load..."), this);

    /*QQuickView *view2 = new QQuickView(); latest attempt. failed.
    QWidget *poi = new QWidget();
    QWidget *container2 = QWidget::createWindowContainer(view2, poi);
    view2->setSource(QUrl("poi.qml"));
    container2->setParent(map);*/

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(button, 0, 0);
    mainLayout->addWidget(map, 3, 0);
    setLayout(mainLayout);

}

analyserQ::~analyserQ()
{

}

poi.qml:

MapCircle {
            center {
                latitude: 59.9485
                longitude: 10.7686
            }
            radius: 50000.0
            color: 'blue'
            border.width: 3
        }

map.qml:

import QtQuick 2.0
import QtLocation 5.5

Rectangle {
     anchors.fill: parent

     Plugin{
        id: osmplugin
        name: "osm"
    }

     Map {
        anchors.fill: parent
        id: map
        plugin: osmplugin;
        zoomLevel: (maximumZoomLevel - minimumZoomLevel)/2//16
        center {
            // The Qt Company in Oslo
            latitude: 59.9485
            longitude: 10.7686
        }

        MapCircle {
            center {
                latitude: 59.9485
                longitude: 10.7686
            }
            radius: 500.0
            color: 'green'
            border.width: 3
        }

    }




}

编辑:我现在正试图通过QML函数来实现,但它不起作用。 我在我的map元素中添加了一个函数addPoi,并试图从c ++代码中调用它。到目前为止没有更多的成功。

function addPoi(latitude, longitude, type) {
            console.log("Got message:");
            circle = Qt.createQmlObject('import QtLocation 5.3; MapCircle {  center{latitude: 59.9485; longitude: 10.7686} }', map, "dynamic");
            if(circle == null) {
               console.log("error creating object" +  circle.errorString());
            }

            circle.radius = 5000.0;
            circle.color = 'blue';
            circle.border.width = 3;
            map.addMapItem(circle);
            return "some return value";
        }

在analyserq.cpp中添加:

QMetaObject::invokeMethod(map, "addPoi",
        Q_RETURN_ARG(QVariant, returnedValue),
        Q_ARG(QVariant, latitude), Q_ARG(QVariant, longitude), Q_ARG(QVariant, type));
    qDebug() << "QML function returned:" << returnedValue.toString();

1 个答案:

答案 0 :(得分:0)

好吧,我设法通过我的代码调用的QML中的JS函数来完成它。以下是相关部分:

analyserq.cpp

    QObject *rootObj;
analyserQ::analyserQ(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    QQuickView *view = new QQuickView();
    QWidget *map = new QWidget();
    QWidget *container = QWidget::createWindowContainer(view, map);
    container->setMinimumSize(400, 450);
    container->setMaximumSize(800, 800);
    container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    container->setFocusPolicy(Qt::TabFocus  );
    view->setSource(QUrl("map.qml"));

    button = new QPushButton(tr("&Load..."), this);
    connect(button, &QAbstractButton::clicked, this, &analyserQ::loadPoI);


    label = new QLabel(tr("Choix Trajets."), this);

    liste = new QComboBox;
    liste->setEditable(false);
    liste->addItem("1");

    loadCombobox();

    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(button, 0, 0);
    mainLayout->addWidget(map, 1, 0);

    mainLayout->addWidget(label, 5, 0);

    mainLayout->addWidget(liste, 5,1);


    setLayout(mainLayout);
    rootObj = view->rootObject();

[...]

void analyserQ::addPoI(QVariant latitude, QVariant longitude, QVariant type)
{
    QVariant returnedValue;

    QMetaObject::invokeMethod(this->rootObj, "addPoi",
        Q_RETURN_ARG(QVariant, returnedValue),
        Q_ARG(QVariant, latitude), Q_ARG(QVariant, longitude), Q_ARG(QVariant, type));
    qDebug() << "QML function returned:" << returnedValue.toString();
}

map.qml

import QtQuick 2.0
import QtLocation 5.5
import QtPositioning 5.2



Rectangle {
     anchors.fill: parent

     Plugin{
        id: osmplugin
        name: "osm"
    }
    function addPoi(lat,longi,type) {
            //console.log("Got message:", lat);
            //console.log("Got message:", longi);
            //console.log("Got message:");
            //var lat = lat;
            var circle = Qt.createQmlObject('import QtLocation 5.3; MapCircle {   }', map, "dynamic");
            if(circle == null) {
               console.log("error creating object" +  circle.errorString());
               return false;
            }
            circle.center = QtPositioning.coordinate(lat, longi);
            circle.radius = 500.0;

            if(type == 0){
                circle.color = 'blue';
            }
            else if(type == 1){
                circle.color = 'yellow';
            }
            else if(type == 2){
                circle.color = 'red';
            }
            else if(type == 3){
                circle.color = 'green';
            }
            circle.border.width = 1;
            map.addMapItem(circle);
            map.center = QtPositioning.coordinate(lat, longi);
            console.log("success creating object");
            return true;
        }

下一步:使PoI可点击......