Search code examples
qtqmlqtlocation

How do I set a property of type QJSValue on a QML object from C++?


I have a QQuickItem that corresponds to a MapPolyline object. The polyline has a property called path, which is defined in the documentation to be of type list<coordinate>. coordinate is a type that maps to QGeoCoordinate in the C++ world. I'm trying to figure out how to set this property's value from C++.

If I check the QMetaObject for the item and look for the type that it reports for the path property, it indicates a type of QJSValue. It's unclear to me how I can set this value from C++ using either QObject::setProperty() or QQmlProperty::write(). I've tried the following:

  • I tried creating a QJSValue that is of array type, with each element holding the coordinate values that I want, something like this:

    void set_property_points(QQuickItem *item, const QVector<QGeoCoordinate> &pointList)
    {
        // Get the QML engine for the item.
        auto engine = qmlEngine(item);
        // Create an array to hold the items.
        auto arr = engine->newArray(pointList.size());
        // Fill in the array.
        for (int i = 0; i < pointList.size(); ++i) arr.setProperty(i, engine->toScriptValue(pointList[i]));
        // Apply the property change.
        item->setProperty("path", arr.toVariant());
    }
    

    This didn't work; the call to setProperty() returns false.

  • I also tried stuffing the list of points into a QVariantList, which seems to be the best match I can find in C++ for a list<coordinate> (QGeoCoordinate is capable of being placed in a QVariant):

    /// Apply a list of `QGeoCoordinate` points to the specified `QQuickItem`'s property.
    void set_property_points(QQuickItem *item, const QVector<QGeoCoordinate> &pointList)
    {
        QVariantList list;
        for (const auto &p : pointList) list.append(QVariant::fromValue(p));
        item->setProperty("path", list);
    }
    

    This didn't work either; same results.

This process doesn't seem to be well-documented. What format do I need to put my data into to make this work?


Solution

  • Turns out that a third approach that isn't mentioned in the documentation actually seems to work. I needed to set the property like this:

    QJSValue arr; // see above for how to initialize `arr`
    item->setProperty("path", QVariant::fromValue(arr));