向 QML 地图添加新地点不起作用

Posted

技术标签:

【中文标题】向 QML 地图添加新地点不起作用【英文标题】:Adding new places to the QML map is not working 【发布时间】:2021-03-24 11:01:55 【问题描述】:

我目前正在创建一个可以在地图上标记地点的程序。

map.qml:

import QtQuick 2.10
import QtQuick.Controls 2.3
import QtLocation 5.6
import QtPositioning 5.6

Rectangle 
    ListModel 
        id: locationModel
    
    Plugin 
        id: mapPlugin
        name: "esri"
    

    Map 
        id: place
        anchors.fill: parent
        plugin: mapPlugin
        center: QtPositioning.coordinate(51.5, 0.1)
        zoomLevel: 7
        MapItemView
        
            model: locationModel
            delegate: mapcomponent
        
    
    Component 
        id: mapcomponent
        MapQuickItem 
            id: marker
            anchorPoint.x: image.width/2
            anchorPoint.y: image.height/2
            coordinate: QtPositioning.coordinate(lat, lon)
            sourceItem: Image 
                id: image
                width: 100
                height: 50
                source: "qrc:/rec/marker.png"
            
        
    
    function addPlace(lat: double, lon: double)
            locationModel.append("lat": lat, "lon": lon)
            console.log("Done")
    

主窗口.cpp:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)

    ui->setupUi(this);
    ui->quickWidget->setSource(QUrl("qrc:/rec/map.qml"));
    QQmlComponent component(ui->quickWidget->engine(), ui->quickWidget->source());
    object = component.create();


/*Some not interesting code.*/

void MainWindow::on_pushButton_4_clicked()

    double lat = 50.00;
    double lon = 20.00;
    QMetaObject::invokeMethod(object, "addDevice",
        Q_ARG(double, lat),
        Q_ARG(double, lon));

object 在 mainwindow.h 中定义如下:QObject *object;add place 函数在单击某个按钮时从 c++ 文件中调用。不幸的是,由于某种原因,此功能无法正常工作。调用它后,控制台中会出现“完成”消息,并且要在地图上标记的点的位置会添加到 ListModel 中。不幸的是,标记没有出现在地图上。我究竟做错了什么?如有任何建议,我将不胜感激。

【问题讨论】:

在 ListModel 中添加 dynamicRoles: true 另外,请仔细检查您的图像资源是否确实已正确添加到您正在使用的路径中的 .qrc 文件中。 可能是仅支持基于 QAbstractItemModel 的模型的问题(来自here) @eyllanesc 我做到了,但还是不行 此处快速说明:此处不需要dynamicRoles: true,因为在这种情况下角色不会改变是基于第一个元素计算的。 ListModelQAbstractItemModel,因此它适用于 MapView。我会接受大卫的建议,或者使用另一个代表来测试它。您可以在委托的 Component.onCompleted 中添加一个 console.log 以确保它已创建。 【参考方案1】:

问题是您正在使用新地图创建一个新组件,并且您正在将标记添加到该新的不可见地图。

与其将 QML 对象暴露给 C++,不如做相反的事情:

#ifndef PLACEHELPER_H
#define PLACEHELPER_H

#include <QObject>

class PlaceHelper : public QObject

    Q_OBJECT
public:
    explicit PlaceHelper(QObject *parent = nullptr);
    void addPlace(double latitude, double longitude);
Q_SIGNALS:
    void add(double latitude, double longitude);
;

#endif // PLACEHELPER_H
#include "placehelper.h"

PlaceHelper::PlaceHelper(QObject *parent) : QObject(parent)




void PlaceHelper::addPlace(double latitude, double longitude)

    Q_EMIT add(latitude, longitude);

*.h

// ..
private:
    Ui::MainWindow *ui;
    PlaceHelper placeHelper;
;

*.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QQmlContext>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)

    ui->setupUi(this);
    ui->quickWidget->rootContext()->setContextProperty("placeHelper", &placeHelper);
    ui->quickWidget->setSource(QUrl("qrc:/rec/map.qml"));


MainWindow::~MainWindow()

    delete ui;


void MainWindow::on_pushButton_4_clicked()

    double lat = 50.00;
    double lon = 0.10;
    placeHelper.addPlace(lat, lon);

import QtQuick 2.10
import QtQuick.Controls 2.3
import QtLocation 5.6
import QtPositioning 5.6

Rectangle 
    ListModel 
        id: locationModel
    
    Plugin 
        id: mapPlugin
        name: "esri"
    

    Map 
        id: place
        anchors.fill: parent
        plugin: mapPlugin
        center: QtPositioning.coordinate(51.5, 0.1)
        zoomLevel: 7
        MapItemView
        
            model: locationModel
            delegate: mapcomponent
        
    
    Component 
        id: mapcomponent
        MapQuickItem 
            id: marker
            anchorPoint.x: image.width/2
            anchorPoint.y: image.height/2
            coordinate: QtPositioning.coordinate(lat, lon)
            sourceItem: Image 
                id: image
                width: 100
                height: 50
                source: "qrc:/rec/marker.png"
            
        
    
    Connections
        target: placeHelper
        function onAdd(latitude, longitude)
            locationModel.append("lat": latitude, "lon": longitude)
        
    


另一种解决方案是将模型用 C++ 实现并导出到 QML:

#ifndef PLACEMODEL_H
#define PLACEMODEL_H

#include <QStandardItemModel>


class PlaceModel: public QStandardItemModel

    Q_OBJECT
public:
    enum PlaceRoles 
        LatitudeRole = Qt::UserRole + 1,
        LongitudeRole
    ;
    PlaceModel(QObject *parent=nullptr);
    Q_INVOKABLE void addPlace(double longitude, double latitude);
;

#endif // PLACEMODEL_H
#include "placemodel.h"

PlaceModel::PlaceModel(QObject *parent):
    QStandardItemModel(parent)

    setItemRoleNames(LatitudeRole, "lat",
                      LongitudeRole, "lon");


void PlaceModel::addPlace(double latitude, double longitude)

    QStandardItem *item = new QStandardItem;
    item->setData(latitude, LatitudeRole);
    item->setData(longitude, LongitudeRole);
    appendRow(item);

*.h

private:
    Ui::MainWindow *ui;
    PlaceModel placeModel;

*.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QQmlContext>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)

    ui->setupUi(this);
    ui->quickWidget->rootContext()->setContextProperty("placeModel", &placeModel);
    ui->quickWidget->setSource(QUrl("qrc:/rec/map.qml"));


MainWindow::~MainWindow()

    delete ui;


void MainWindow::on_pushButton_4_clicked()

    double lat = 50.00;
    double lon = 0.10;
    placeModel.addPlace(lat, lon);

import QtQuick 2.10
import QtQuick.Controls 2.3
import QtLocation 5.6
import QtPositioning 5.6

Rectangle 
    Plugin 
        id: mapPlugin
        name: "esri"
    

    Map 
        id: place
        anchors.fill: parent
        plugin: mapPlugin
        center: QtPositioning.coordinate(51.5, 0.1)
        zoomLevel: 7
        MapItemView
        
            id: mapView
            model: placeModel
            delegate: mapcomponent
        
    
    Component 
        id: mapcomponent
        MapQuickItem 
            id: marker
            anchorPoint.x: image.width/2
            anchorPoint.y: image.height/2
            coordinate: QtPositioning.coordinate(lat, lon)
            sourceItem: Image 
                id: image
                width: 100
                height: 50
                source: "qrc:/rec/marker.png"
            
        
    

【讨论】:

以上是关于向 QML 地图添加新地点不起作用的主要内容,如果未能解决你的问题,请参考以下文章

向 ASP.Net MVC 5 添加新主题不起作用

谷歌地图API地方自动完成getPlace()不起作用

谷歌地图 api 地理定位和地点搜索

QML:鼠标悬停不起作用

学说迁移:向现有表添加和删除两个外键列不起作用

QML 状态不起作用