Important: Please read the Qt Code of Conduct -

Map (QDeclarativeGraphicsGeoMap) Can't Append Map Objects

  • Why is it not possible to append map objects like MapCircle to a Map?

    A few issues I identified:

    1. Map objects (eg. MapCircle) are not considered 'graphical items'. Hence, you cannot re-parent them. Because of this you can't use Qt.createQmlObject/Qt.createObject or parent property to assign it to a Map.

    2. Map has no append function in QML. Although an append function is provided in the C++ type and passed to the QML, there is no way to use an append function within QML other than via initialisation (which entirely defeats the purpose). The list itself is read-only.

    3. You can't initialise lists. Great, you can initialise objects. So you could just store a list and then re-initialise when the list changes. Nope. First off - what's a list? Javascript lists don't work. Second, it seems to reject multiple items. objects = a (works!), objects = b (works!), objects = [a,b] (doesn't work)
      The devs say it is an issue with javascript binding.

    The only way I have found to workaround this is to modify the QtMobility code or entirely re-create the Map types in the C++ wrapper or a plugin.

    It's something so simple though (for QtMobility devs).

    All you need to add to QDeclarativeGraphicsGeoMap.cpp is:
    @void QDeclarativeGraphicsGeoMap::addMapObject(QGeoMapObject* mapObj)
    if (mapData_)

    Does anyone have a better workaround?

  • For these sort of things I normally end up having a "global" object that allows me to expose functionality that usually isn't, something like how the Qt "class" works from QML.

    So I'd add a Q_INVOKABLE function like this to this global object:

    @Q_INVOKABLE addMapObjectToGeoMap(QDeclarativeGraphicsGeoMap gm, QGeoMapObject mapObj) { /* stuff */ }@

    Then call it from QML like:

    @global.addMapObjectToGeoMap(thing1, thing2)@

    I'm guessing it's also possible to work around this using extension objects ("Extension Objects": but I've never played with those.

  • Well I found it really complicated to sub-class. I guess that's what you're suggesting. First off, I need Qt Mobility namespace. OK, that's easy enough but seems to have caused some problems. Second off, I need to include all the location-relevant headers (these aren't just for QtMobility). I did all this and it was giving vague errors that I couldn't decipher.

    If this global object isn't a sub-classed QDeclarativeGraphicsGeoMap, can you suggest how it is done?

    Anyway, I ended up changing the class in QtMobility. Unfortunately, it is annoying to have to re-compile a custom qtmobility.

  • My global isn't a subclass, it's literally a global QObject derived class I dump things into that would otherwise be stand alone functions within a C++ context. An example would be how qRgba() is a free standing function when called from C++, but it's called as Qt.qRgba().

    I don't have simple running example on me, but it's just something like:
    @#include <QObject>
    #include <QtMobility> /* or whatever the header is, I admit I haven't touched it */

    class Global : public QObject
    explicit Global(QObject *parent = 0);

    Q_INVOKABLE addMapObjectToGeoMap(QDeclarativeGraphicsGeoMap *gm, QGeoMapObject* mapObj)
    { /* stuff */ }


    public slots:


    Then somewhere else you'd register an instantation of the class (main.cpp or whatever).

    @ qmlRegisterType<Global>("MyNamespace", 1,0, "Global");
    Global *global = new Global();
    viewer.rootContext()->setContextProperty("global", global);

    Then call it as above.

    Though of course after writing this I've realised the problem is that all the values you need to modify are in the private section of the QDeclarativeGraphicsGeoMap class so you can't access them anyway. Even deriving your own class isn't going to help with that unless you're going to do hacky things to get around the private thing.

  • Oh I see. The problem is you need to include QDeclarativeGraphicsGeoMap in the C++. You may as well derive it as a class really. It has the same requirements but I see your point.

    Problem is I can't include QDeclarativeGraphicsGeoMap (it's a declarative type and not part of QtMobility headers) and it has those Qt Mobility namespaces.

  • The issue with deriving from it's class is you have the mass of headers in a .h file polluting your other files, rather then tucking the collection of private headers away inside a .cpp file and just using "class QDeclarativeGraphicsGeoMap;" etc in the .h file. Plus it means you have a lot more control over exactly what might be conflicting with the private headers and such too.

    In any event I don't think there's any good solution to the problem. Either you need to hack the mobility code to include that function; or you need to something like the above then #include an _p.h private api (and hope it doesn't break) into your cpp file and do something like:

    @#define private public
    #include "the/relevant/private/api/file_p.h"

    /* code goes here */

    #undef private

    And hope name mangling doesn't include it's access level (I don't think it does in gcc).

Log in to reply