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
)?
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
派生类型中,您实现一个接口来获取给定索引处的列表和各个点的大小。您基本上为点列表实现了一个独立的访问器/操纵器。一切都准备好了。
我也
强烈建议在这种情况下使用QVector
而不是
QList
。
class PlaneGridQML : public QObject
{
Q_OBJECT
........
Q_INVOKABLE QPoint get(int i) { return planesPoints[i]; }
...
}
...
console.log(PlaneGrid.get(0).x)
如果你只有一个平面网格和一组点,你甚至不需要将不透明指针传递给QML,你可以直接使用平面网格通过索引获取大小和单个元素。简单易行。
QPoint
公开给 QML,但不能公开
QList<QPoint>
。 我看到了解决您问题的三种可能的解决方案:
PlaneGridQML::planesPointsChanged
信号添加参数。您不能公开
QList<QPoint>
,但可以发送两个
QList<qreal>
类型的变量作为信号参数。一个列表可以包含
x
值和另一个
y
值。
int PlaneGridQML::getPlanesPointsCount()
和
QPoint PlaneGridQML::getPlanesPoint(int index)
。所以你有两个函数 - 第一个返回有多少个点,第二个返回每个索引的点。
planePointX
,
planePointY
)并返回
QQmlListProperty<NewClass>
和
PlaneGridQML::getPlanesPoints
。然而,对于您的情况来说,这种方法并不是一个好主意(太复杂)。更多信息。
要解决该问题,只需使用 QVariant::fromValue 将列表作为 QVariant 传回即可。
例如:
Q_INVOKABLE QVariant getPlanesPoints() {
QPoint p1(1,1);
QPoint p2(2,2);
QPoint p3(3,3);
QList<QPoint> plist;
plist << p1 << p2 << p3;
return QVariant::fromValue(plist);
}
然后在 QML 中:
Connections {
target: PlaneGrid
onPlanesPointsChanged: {
var pointsArray = PlaneGrid.getPlanesPoints()
console.log(pointsArray[0].x)
}
}