【问题标题】:Handling complex object trees in QML's model-view-delegate system?在 QML 的模型-视图-委托系统中处理复杂的对象树?
【发布时间】:2019-12-07 17:03:25
【问题描述】:

我将 QML 与 PyQt 一起使用,这两个与 Qt 的信号/插槽系统进行通信。我有已序列化为 JSON 格式的 Python 对象,例如其中出售的商店和商品的列表:

[
  {
    "store": "Walmart",
    "items": [
      {
        "name": "banana",
        "price": 0.95
      },
      ...
    ]
  },
  {
    "store": "Target",
    "items": [...]
  },
  ...
]

然后将其与信号一起转发到 QML,然后我将整个 JSON 结构存储到单个变量中,我们称之为stores

// main.qml
Window {
    id: app
    property var stores: []

    // Slot function that's connected to Python
    function onStoresInitialized(stores) {
        app.stores = stores;
    }
}

现在我有一个像这样的ListView

ListView {
    model: app.stores
    delegate: Column {
        Repeater {
            model: modelData["items"]
            Text {
                text: modelData["name"] + " $" + modelData["price"]
            }
        }
    }
}

虽然该示例已大大简化,但到目前为止似乎一切正常。当我想更新单个商品时,就会出现问题,比如我们从 Python 收到一个特定商品价格已更新的信号。我们的 QML 插槽看起来像这样:

function updatePrice(storeName, itemName, newPrice) {
    for (let store : app.stores) {
        if (store["name"] === storeName) {
            for (let item : store["items"]) {
                if (item["name"] === itemName) {
                    item["price"] = newPrice;
                    return;
                }   
            }
        }
    }
}

这会正确更新我的“模型”中的价格,但并不表示对此更改的看法。我认为使用原始数据作为模型不是正确的方法,但什么是正确的方法?所有的 QML 指南似乎都使用简单的数据示例,例如带有 ListModelListElements 的一维项目列表,但是当我有像这里这样的深层对象树时该怎么办?

【问题讨论】:

    标签: python model-view-controller pyqt qml


    【解决方案1】:

    我的 QML 时代已经结束了,但解决此问题的一种方法是将整个 JSON 包装到使用 PyQt 制作的自定义对象图中,将各个属性公开为pyqtProperty。然后将 JSON 按摩到此对象树中。我们使用从 Python 中的模型规范生成的 C++ 模型来执行此操作。为什么会这样说来话长,但它允许我们通过网络发送 JSON。

    可能有一种方法可以使用 QML 类型在 QML 本身中完成所有这些操作,但我个人更喜欢在 Python 中创建模型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-14
      相关资源
      最近更新 更多