前言
接上篇,上篇写到图结构的可视化,这一篇介绍实时曲线图。
实现效果
代码实现
该绘图方法使用QCustomPlot,定义一个继承自QCustomPlot的类Qcurve。
曲线管理
在类中,使用一个map管理各条曲线
QMap<QString, QPointer<QCPGraph>> mGraph;
图例显示:
在类的构造函数中使用
this->legend->setVisible(true);
以显示图例
定时刷新:
使用一个定时器进行定时刷新
timerTick = new QTimer();
timerTick->setInterval(50);
connect(timerTick,SIGNAL(timeout()),this,SLOT(tick()));
timerTick->start();
void QCurve::tick()
{
this->replot();
}
添加和删除曲线
添加曲线
bool addCurve(QString linename)
{
if(!mGraph.contains(linename))
{
QPointer<QCPGraph> graph = this->addGraph(this->xAxis,this->yAxis);
graph->setName(linename);
colorindex++;
colorindex = colorindex%18;
QPen pen = QPen(baseColors[colorindex]);
pen.setWidth(m_width);
graph->setPen(pen);
mGraph.insert(linename,graph);
return true;
}
else
return false;
}
删除曲线
bool deleteCurve(QString linename)
{
if(mGraph.contains(linename))
{
auto graphit = mGraph.find(linename);
this->removeGraph(graphit.value());
mGraph.remove(linename);
return true;
}
else
{
return false;
}
}
添加数据
bool addData(QString linename,int ms, double data)
{
if(mGraph.contains(linename))
{
auto graphit = mGraph.find(linename);
graphit.value()->addData(ms,data);
if(graphit.value().data()->dataCount()>m_range)
graphit.value()->removeDataBefore(m_range);
this->xAxis->rescale();
graphit.value()->rescaleValueAxis(!firstdata, true);
this->xAxis->setRange(this->xAxis->range().upper, m_range, Qt::AlignRight);
firstdata = false;
return true;
}
else //没有则添加
{
if(addCurve(linename))
return true;
return false;
}
}
修改QCustomPlot源码
本文使用个v2.0.1的qcustomplot,没有了v1.x版本的removeDataBefore函数,因此修改qcustomplot源码进行添加,在QCPGraph类中增加如下公有成员函数。
void QCPGraph::removeDataBefore(int size)
{
mDataContainer->removeBefore(mDataContainer->size()-size);
}
如何使用
将Qcurve加入到界面,或者可以直接提升控件。
curve = new QCurve();
QGridLayout *curvegrid = new QGridLayout(ui->tab_curve2);
curvegrid->addWidget(curve);
添加和删除曲线
curve->addCurve(linename);
curve->deleteCurve(linename);
添加数据
curve->addData(linename,time,data);
使用建议
在使用时笔者倾向于使用map对所有曲线进行管理。
QMap<QString,int> curveManager;
curveManager.insert(linename, value);
curveManager.remove(linename);
其中value存放linename所需绘图数据的索引。在需要更新界面时,使用curveManager会比较方便。
for(auto it = curveManager.begin();it!=curveManager.end();it++)
{
int time = alldata[it.value()].time;
double data = alldata[it.value()].data;
curve->addData(it.key(),time,data);
}