gpt4 book ai didi

c++ - QT通过C++添加Map QML Items

转载 作者:行者123 更新时间:2023-12-02 10:05:29 24 4
gpt4 key购买 nike

我尝试从 C++ 向我的 map 添加 QML map 项,例如 MapQuickItem 或 MapCircle。不幸的是,它们没有显示在 map 上。只需一个 QML 矩形的相同代码就可以工作。rect v1 是用于测试的矩形。 rect v2 是不起作用的 mapCircle。当我将我的圈子 QML 代码 1:1 添加到我的 map QML 代码中时,它工作正常。

ma​​in.cpp:

int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);

QQuickView *view = new QQuickView;
view->setSource(QUrl("qrc:/map.qml"));

QQmlComponent compRect (view->engine(), QUrl("qrc:/rect.qml"));

view->setWidth(1000);
view->setHeight(650);
view->setTitle("GUI");


QQuickItem *map = view->findChild<QQuickItem*>("map1");

QQuickItem *rect = qobject_cast<QQuickItem*>(compRect.create(view->rootContext()));

rect->setParentItem(map);
rect->setParent(map); //know this is not for visual objects, just for test

view->show();
return app.exec();
}

rect.qml v1

import QtQuick 2.14
import QtLocation 5.14
import QtPositioning 5.14

Rectangle
{
color: "grey"
opacity: .8

width: 100
height: 100
radius: 4
Text
{
id: text
anchors.centerIn: parent
text: "hi"
color: "orangered"
font.weight: Font.Bold
}
}

rect.qml v2

import QtQuick 2.14
import QtLocation 5.14
import QtPositioning 5.14

MapCircle
{
center
{
latitude: 47.5
longitude: 8.9
}
radius: 5000.0
color: 'green'
border.width: 3
}

ma​​p.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtPositioning 5.14
import QtLocation 5.14

Map
{
objectName: "map1"
id: map_map
anchors.centerIn: parent;
anchors.fill: parent
plugin: Plugin
{
name: "mapboxgl" // "osm", "esri", ...
}
center: QtPositioning.coordinate(47.6,9.5)
zoomLevel: 8

// get position of device and set map center to it
PositionSource
{
active: true
onPositionChanged:
{
map.center(position.coordinate)
console.log(position.coordinate)
}
}

Timer
{
id: timerReload
interval: 1000
repeat: true
running: true

onTriggered:
{
controller.triggerReload();
}
}
}

最佳答案

确定一个项目是 map 的子项并不意味着它显示在 map 上,如果你想添加一个项目你必须使用 addMapItem()方法,在 C++ 中你可以使用 QMetaObject::invokeMethod()调用该方法,但您需要访问属于私有(private) Qt API 的类型 QDeclarativeGeoMapItemBase,考虑到上述解决方案是:

*.pro

QT += quick location location-private
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp
RESOURCES += qml.qrc

main.cpp

#include <QGuiApplication>
#include <QQuickItem>
#include <QQuickView>

#include <QtLocation/private/qdeclarativegeomapitembase_p.h>

int main(int argc, char *argv[]){
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl("qrc:/map.qml"));
view.resize(1000, 650);
view.setTitle("GUI");
view.show();
if(QQuickItem *map = view.findChild<QQuickItem*>("map1")){
QQmlComponent component(view.engine(), QUrl("qrc:/rect.qml"));
if(QDeclarativeGeoMapItemBase *rect = qobject_cast<QDeclarativeGeoMapItemBase*>(component.create(view.rootContext()))){
bool status = QMetaObject::invokeMethod(map,
"addMapItem",
Qt::DirectConnection,
Q_ARG(QDeclarativeGeoMapItemBase*, rect));
Q_ASSERT(status);
}
}
return app.exec();
}

前面的方法的问题是很危险,因为 map 或任何QML元素随时都可能被移除,这样就可能产生问题,而且它限制了QML的修改,最后需要访问私有(private) Qt API 可以更改,恕不另行通知。因此我会提供更好的选择:

  • 使用 QObject 并将其导出到 QML,在 QML 中创建项目并将其添加到 map :

    #include <QGuiApplication>
    #include <QQuickView>
    #include <QGeoCoordinate>
    #include <QQmlContext>

    class Helper: public QObject{
    Q_OBJECT
    public:
    void addCircle(const QGeoCoordinate & coordinate){
    Q_EMIT circleSignal(coordinate);
    }
    Q_SIGNALS:
    void circleSignal(const QGeoCoordinate & coordinate);
    };

    int main(int argc, char *argv[]){
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQuickView view;
    Helper helper;
    view.rootContext()->setContextProperty("helper", &helper);
    view.setSource(QUrl("qrc:/map.qml"));
    view.resize(1000, 650);
    view.setTitle("GUI");
    view.show();
    helper.addCircle(QGeoCoordinate(47.6, 9.5));
    return app.exec();
    }

    #include "main.moc"
    import QtQuick 2.14
    import QtPositioning 5.14
    import QtLocation 5.14

    Map{
    id: map_map
    anchors.centerIn: parent;
    anchors.fill: parent
    plugin: Plugin {
    name: "mapboxgl" // "osm", "esri", ...
    }
    center: QtPositioning.coordinate(47.6,9.5)
    zoomLevel: 8
    Connections{
    target: helper
    onCircleSignal: {
    var component = Qt.createComponent("rect.qml");
    if (component.status === Component.Ready){
    var o = component.createObject(map_map);
    o.center = coordinate
    map_map.addMapItem(o)
    }
    }
    }
    }

    import QtQuick 2.14
    import QtPositioning 5.14
    import QtLocation 5.14

    Map{
    id: map_map
    anchors.centerIn: parent;
    anchors.fill: parent
    plugin: Plugin {
    name: "mapboxgl" // "osm", "esri", ...
    }
    center: QtPositioning.coordinate(47.6,9.5)
    zoomLevel: 8

    Component{
    id: provider
    MapCircle{
    center{
    latitude: 47.6
    longitude: 9.5
    }
    radius: 5000.0
    color: 'green'
    border.width: 3
    }
    }
    function createCirle(map, position){
    var o = provider.createObject(map)
    o.center = position
    map.addMapItem(o)
    return o
    }

    Connections{
    target: helper
    onCircleSignal: {
    var o = createCirle(map_map, coordinate)
    }
    }
    }
  • 将模型与 MapItemView 结合使用:

    #include <QGuiApplication>
    #include <QQuickView>
    #include <QGeoCoordinate>
    #include <QQmlContext>
    #include <QStandardItemModel>

    int CoordinateRole = Qt::UserRole + 1000;

    int main(int argc, char *argv[]){
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQuickView view;
    QStandardItemModel model;
    QHash<int, QByteArray> roles;
    roles[CoordinateRole] = QByteArray("coordinate");
    model.setItemRoleNames(roles);
    view.rootContext()->setContextProperty("circle_model", &model);
    view.setSource(QUrl("qrc:/map.qml"));
    view.resize(1000, 650);
    view.setTitle("GUI");
    view.show();

    QStandardItem *item = new QStandardItem;
    item->setData(QVariant::fromValue(QGeoCoordinate(47.6, 9.5)), CoordinateRole);
    model.appendRow(item);

    return app.exec();
    }
    import QtQuick 2.14
    import QtPositioning 5.14
    import QtLocation 5.14

    Map{
    id: map_map
    anchors.centerIn: parent;
    anchors.fill: parent
    plugin: Plugin {
    name: "mapboxgl" // "osm", "esri", ...
    }
    center: QtPositioning.coordinate(47.6,9.5)
    zoomLevel: 8

    MapItemView{
    model: circle_model
    delegate: MapCircle{
    center: model.coordinate
    radius: 5000.0
    color: 'green'
    border.width: 3
    }
    }
    }

关于c++ - QT通过C++添加Map QML Items,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60377720/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com