QXYSeries*对象能否使用QQueue<QPointF>替换数据点?
问题解答
该需求完全可以实现,无需做全量数据拷贝,也不需要使用低效的逐个append()操作。
实现原理
QQueue<QPointF>本身是QList<QPointF>的公有派生类,仅在QList的基础上封装了队列特有的入队、出队、取队头元素的接口,底层存储结构和QList完全一致。
QXYSeries的replace()方法本身就提供了接收const QList<QPointF>&类型参数的重载,你用QQueue维护点位的逻辑完全不需要改动,可以直接把队列对象传入replace(),不会产生额外的数据拷贝开销。
代码示例
你可以按照原有逻辑用QQueue维护滚动更新的点位,比如固定长度的示波器波形缓存:
// 定义单屏最多显示的点位数量 const int MAX_DISPLAY_POINTS = 1000; QQueue<QPointF> wavePoints; // 新采集到点位时入队 qreal newX = getLatestX(); qreal newY = getLatestY(); wavePoints.enqueue(QPointF(newX, newY)); // 超出缓存长度时移除最早的旧点位 if (wavePoints.size() > MAX_DISPLAY_POINTS) { wavePoints.dequeue(); } // 直接把队列传入replace完成全量更新,无需转QVector xySeries->replace(wavePoints);
特殊版本兼容说明
如果你使用的Qt版本较旧,replace()仅提供了接收QVector<QPointF>的重载,也不需要循环调用append(),可以直接用QVector的静态方法构造入参:
xySeries->replace(QVector<QPointF>::fromList(wavePoints));
由于Qt容器全部采用隐式共享(写时复制)机制,这个转换不会立刻触发全量数据拷贝,仅当你后续修改队列或者生成的QVector内容时才会执行深拷贝,性能损耗几乎可以忽略。
性能优化提示
- 不要使用逐个点调用
append()、remove()的方式更新序列,这类操作每修改一个点就会触发一次图表的布局计算和重绘信号,性能比一次性replace()差10倍以上 - 如果点位规模超过5000个,可以开启序列的OpenGL渲染加速,调用
xySeries->setUseOpenGL(true)即可,大点位量下帧率提升非常明显 - 尽量给QQueue设置固定的最大缓存长度,不要无限制存储点位,避免不必要的内存占用
内容的提问来源于stack exchange,提问作者Crystal
相关产品推荐
相关产品推荐

