Unsolved Custom QQuickItem: Updating Geometry
-
Hi,
I have a custom QQuickItem which I use to display a x,y graph coming from a measurement device. If the measurement device delivers new data, I need to reset the QSGGeometry. I wonder whether it is possible to only append points to the end of the geometry instead of resetting it completely.
-
Isn't
QSGGeometry::allocate
is what you need? -
Maybe :-). I tried it, but sometimes I receive a segfault. I should note that I guess I did not follow this rule:
"The rule of thumb is to only use classes with the "QSG" prefix inside the QQuickItem::updatePaintNode() function." from https://doc.qt.io/qt-5.9/qtquick-visualcanvas-scenegraph.html
So I guess the problem is that I might not call it in the right place
My approach:The geometry is a member of the class.
class PlotCurve : public QQuickItem { public: void updateGeometry(const std::vector<double>* xdata, const std::vector<double>* ydata); private: QSGGeometry * _geometry; QSGGeometryNode * _curve;
When I had static x and y data, I set it in the constructor like this:
_geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(),xdata->size()); QSGGeometry::Point2D *points = _geometry->vertexDataAsPoint2D(); for(int i=0;i<xdata->size();i++) { points[i].x = xdata->at(i); points[i].y = view_y_range-ydata->at(i)+_view_y_min; }
Here is my updateGeoemtry function
_geometry->allocate(xdata->size()); QSGGeometry::Point2D *points = _geometry->vertexDataAsPoint2D(); for(int i=0;i<xdata->size();i++) { points[i].x = xdata->at(i); points[i].y = (_view_y_max-_view_y_min)-ydata->at(i)+_view_y_min; } _curve->markDirty(QSGNode::DirtyGeometry);
and here my updatePaintNode
QSGNode *PlotCurve::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { QSGNode * mainNode = oldNode; if(!mainNode) { mainNode = new QSGNode; } if(!_transformNode) { _transformNode = new QSGTransformNode; mainNode->appendChildNode(_transformNode); } if(!_curve) { _geometry->setLineWidth(_curve_width); _geometry->setDrawingMode(GL_LINE_STRIP); _curve = new QSGGeometryNode; _curve->setFlag(QSGNode::OwnsMaterial,true); _curve->setFlag(QSGNode::OwnsGeometry,true); _curve->setGeometry(_geometry); QSGFlatColorMaterial* material = new QSGFlatColorMaterial; material->setColor(_curve_color); _curve->setMaterial(material); _transformNode->appendChildNode(_curve); } double transX = -_view_x_min; double transY = -(_view_y_max_init-_view_y_max); QMatrix4x4 m; m.scale(_scaleFactorX,_scaleFactorY); m.translate(transX, transY); _transformNode->setMatrix(m); return mainNode; }
-
So what is the correct way to update the geometry of a QQuickItem? In my case, the xdata and ydata vectors would simply grow with time and the data before would remain the same
-
No one is creating his own QQuickItems with changing geometry?