【问题标题】:Reading a QList<QPoint> in QML在 QML 中读取 QList<QPoint>
【发布时间】:2017-08-08 18:03:27
【问题描述】:

我有以下类定义:

class PlaneGridQML : public QObject
{
    Q_OBJECT
    ........
    Q_INVOKABLE QList<QPoint> getPlanesPoints() {
        return m_PlaneGrid.getPlanesPoints();
    ......
}

我主要是让 QML 引擎可以使用它

PlaneGridQML pgq(10, 10, 3, false);
engine.rootContext()->setContextProperty("PlaneGrid",&pgq);

然后在 QML 组件中,我想执行以下操作:

Connections {
    target: PlaneGrid
    onPlanesPointsChanged: {
        var pointsArray = PlaneGrid.getPlanesPoints()
        console.log(pointsArray[0].x)
    }
}

我收到错误“未知方法返回类型:QList”,显然我无法读取 pointsArray 并显示其第一个成员。根据 Qt 文档 QPoint 可以直接作为 JS 类型调用。另一方面,QPoint 不是从QObject 派生的。

谁能解释我如何在 JS 函数中列出数组的元素(QPoints)?

【问题讨论】:

    标签: c++ qt qml


    【解决方案1】:

    是的,QPoint 将自动转换为 QML,甚至某些对象的 QList 也会自动转换为 QML,但仅仅因为 QList&lt;int&gt; 有效且 QPoint 有效,这并不意味着QList&lt;QPoint&gt; 也可以使用。

    这是 QML 支持的列表中的自动类型列表:

    QList<int>
    QList<qreal>
    QList<bool>
    QList<QString> and QStringList
    QList<QUrl>
    QVector<int>
    QVector<qreal>
    QVector<bool>
    

    如您所见,QPoint 不是其中之一。

    QObject 包裹会很浪费。

    但不要绝望。我建议您将QList&lt;QPoint&gt; * 声明为元类型,然后您可以将其包装在QVariant 中以将其作为不透明的指针传递给QML。然后,在您的 PlaneGridQML 或另一个单一的 QObject 派生类型中,您实现一个接口来获取列表的大小和给定索引处的各个点。

    您基本上为点列表实现了一个独立的访问器/操纵器。一切就绪。

    我还 strongly recommend 说你在这种情况下使用 QVector 而不是 QList

    class PlaneGridQML : public QObject
    {
        Q_OBJECT
        ........
        Q_INVOKABLE QPoint get(int i) { return planesPoints[i]; }
        ...
    }
    ...
    console.log(PlaneGrid.get(0).x)
    

    如果你只有一个平面网格和一组点,你甚至不需要将不透明指针传递给 QML,你可以直接使用平面网格通过索引获取大小和单个元素。轻松愉快。

    【讨论】:

    • 我认为 QList (QVariantList) 应该也可以工作 - 只是为了你的列表的完整性......但我可能会犯错。
    • QVariantList 有效,但您必须将所有点转换为变体......听起来不是一个好主意。
    • @dtech 请允许我几天时间来验证您的建议。
    • @dtech 使用不透明指针方法时如何读取 JS 代码中的数据?
    • @Cristi 您必须将其传递回 C++,将其转换回其实际类型并简单地使用它来获取数据。所以它在 QML Accessor.get(listVar, index) 中会是这样的,在 C++ 中你会像 listVar.value&lt;QList&lt;QPoint&gt;*&gt;()-&gt;at(index) 这样。但同样,不要使用QList :)
    【解决方案2】:

    您可以将QPoint 公开给QML,但不能公开QList&lt;QPoint&gt;。 对于您的问题,我看到了三种可能的解决方案:

    1. PlaneGridQML::planesPointsChanged 信号添加参数。您不能公开QList&lt;QPoint&gt;,但可以发送两个QList&lt;qreal&gt; 类型的变量作为信号参数。一个列表可以包含 x 值和另一个 y 值。
    2. 实现int PlaneGridQML::getPlanesPointsCount()QPoint PlaneGridQML::getPlanesPoint(int index)。所以你有两个函数 - 一个返回有多少点,第二个返回每个索引的点。
    3. 创建一个新类,该类将包含两个变量(planePointXplanePointY)并返回QQmlListProperty&lt;NewClass&gt;PlaneGridQML::getPlanesPoints。但是,对于您的情况(太复杂),这种方法并不是一个好主意。 More info

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      • 1970-01-01
      相关资源
      最近更新 更多