在QML

时间:2017-08-08 18:03:27

标签: c++ qt qml

我有以下类定义:

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)?

2 个答案:

答案 0 :(得分:3)

是的,QPoint会自动转换为QML,甚至某些对象的QList也会自动转换为QML,但只是因为QList<int>有效且QPoint工作,没有必要意味着QList<QPoint>也会起作用。

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

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

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

QObject包裹起来将是一种浪费。

但不要绝望。我建议你将QList<QPoint> *声明为元类型,然后你可以将其包含在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,您可以直接使用平面网格通过索引获取大小和单个元素。容易腻。

答案 1 :(得分:0)

您可以将QPoint公开给QML,但不公开QList<QPoint>。 我看到了三个可能的问题解决方案:

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