Qt5 QML QVariantMap 与更改通知绑定

Qt5 QML QVariantMap Binding with change notifications

我有 QVariantMap(不是 QObject,因为 属性 名称未预定义)。我将 QVariantMap 注入 QML 根上下文以使用 属性 值进行绑定。

问题是,当我更改 QVariantMap 或什至当我更改 QVariantMap 并为更新的对象调用 setContextProperty 时,或者当我更新(使用 fromValue)由 contextProperty 返回的对象时,没有任何反应。所以这看起来像是一次性绑定。

那么,以可观察的方式将 Map 或 Map 注入 QML 上下文的正确方法是什么,以便地图中更改的项目将反映在 QML 中?

您可以创建一个具有 QVariantMap 属性 的 QObject 并将该对象设置为 contextObject(有关 contextObject 的文档,请参阅 http://doc.qt.io/qt-5/qqmlcontext.html#details)。在您的 QML 中,您可以在全局范围内使用 "map" 属性,它应该在您调用 MyVariantMap::setMap() 时更新。

class MyVariantMap : public QObject {
    Q_OBJECT
    Q_PROPERTY(QVariantMap map READ map WRITE setMap NOTIFY mapChanged)

public:
    QVariantMap map() const { return Map; }
    void setMap(QVariantMap map) {
       if(Map != map) {
           Map = map;
           emit mapChanged()
       }
    }

signals:
 void mapChanged();

private:
    QVariantMap Map;

};

要将 C++ 映射公开给 QML,而不创建派生的 QObject class,您可以使用 QQmlPropertyMap

main.cpp

// create our data
QQmlPropertyMap ownerData;
ownerData.insert("name", QVariant(QString("John Smith")));
ownerData.insert("phone", QVariant(QString("555-5555")));
// expose it to the UI layer
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("owner", &ownerData);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

main.qml

Window {
    Text { text: owner.name + " " + owner.phone }
}

绑定是动态的 - 每当更新键的值时,绑定到该键的任何内容也会更新。不需要每次更改 QQmlPropertyMap.

时都调用 setContextProperty