最近要求在项目中做一组数据的动态曲线,由于本人之前做过MFC的图像显示,深知MFC开发之别扭,瑟瑟发抖,后来听说QT很方便,确实在熟悉之后发现着实好用。
绘制动态曲线,关键是在曲线数据以及坐标轴的更新。笔者采用定时器拾取进行曲线数据的更新,数据更新包括坐标轴和坐标点的更新。随着时间的推移,实际的参量对应坐标轴的意义已经不在是单纯的x,y。而是根据需求赋予坐标轴更为贴切的含义,例如位置,距离等。同时坐标轴也要更新以适应曲线。在确定好显示画布之后,显示面的数据个数设置一定,增加新数据或者替换掉旧的数据。做上位机界面时,要绘制从下位机收到数据的曲线,需要有一个接收数据的buffer或QList<string>datalist或者采用QVector。采用qlist可方便地去掉数据头和新增数据。这样可保证数据的流动性稳定,不会造成内存的消耗。如果通过append实现数据的更新,此方法是将增加的数据和原来你的数据头尾相连形成一体,这样会导致缓冲区数据堆积,吃内存现象明显,时间久了程序比较卡顿。对于程序的初始化部分,大同小异,这里就不在赘述,因此采用replace的方式更新数据才是最好的选择。具体代码如下:
void Widget::timerEvent(QTimerEvent *event){
if(event->timerId()==timeId){//定时器到时间
int size=500;//数据个数
if(isVisible()){
QVector<QVector<QPointF>>oldPoints(3);
QVector<QVector<QPointF>>points(3);
for(int i=0;i<3;i++)
{
oldPoints[i]=m_series[i]->pointsVector();
for(int s=size;s<oldPoints.at(i).count();++s)
{
points[i].append(QPointF(s-size,oldPoints.at(i).at(s).y())); //替换数据用 移动数据用
}
qint64 sizePoints = points.at(i).count();
for(int k=0;k<size;++k)
{
points[i].append(QPointF(k+sizePoints,getData((((double)newdata+k+1)/1000))));
}
m_series[i]->replace(points.at(i));
}
}
}
}