一个嵌入式项目,项目需要使用QCustomPlot绘图。目前的工作逻辑是定时器周期性触发数据设置并调用replot()函数重绘。
此处的QCustomPlot控件放置在MainWindow上,命名为chrtData。
禁止抗锯齿
通过以下调用,停用抗锯齿功能:
QFont fntAxisFont(ui->chrtData->xAxis->tickLabelFont());
fntAxisFont.setStyleStrategy(QFont::NoAntialias);
ui->chrtData->xAxis->setTickLabelFont(fntAxisFont);
fntAxisFont=ui->chrtData->yAxis->tickLabelFont();
fntAxisFont.setStyleStrategy(QFont::NoAntialias);
ui->chrtData->yAxis->setTickLabelFont(fntAxisFont);
ui->chrtData->graph(0)->setAntialiased(false);
ui->chrtData->graph(0)->setAntialiasedFill(false);
ui->chrtData->graph(0)->setAntialiasedScatters(false);
ui->chrtData->setNotAntialiasedElements(QCP::aeAll);
ui->chrtData->setNoAntialiasingOnDrag(true);
不使用宽度大于1的线
宽度大于1的线会带来明显的性能损耗:
ui->chrtData->graph(0)->setPen(QPen(QColor(0,150,245),1));
ui->chrtData->graph(0)->setLineStyle(QCPGraph::lsLine);
评估使用QApplication::processEvents()带来的性能折损
起初尝试使用QApplication::processEvents()和qApp->processEvents()保证响应性,但是定时器调用的频率并不会造成严重的阻滞。
评估单独重绘图层的意义
QCustomPlot推荐在同时存在多个数据量和更新速率差异极大的曲线时使用图层,并分别在不同时机调用不同图层的replot()函数进行重绘。
但是,如果只有单一数据,通过layer("main")->replot()单独重绘main图层会导致严重的性能折损。
使用replot()时传入QCustomPlot::rpQueuedReplot作为参数
这是一个QCustomPlot作者推荐的用于处理频繁replot()调用的做法,来减少冗余的重绘。
使用Raster绘图系统
由于目标机没有提供OpenGL库,因此根据QCustomPlot作者的推荐,使用Raster替代默认的Native绘图系统。
在main.cpp中的int main(int argc, char *argv[])函数内,在QApplication a(argc, argv);代码行前加入:
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
QApplication::setGraphicsSystem("raster");
#endif
或在目标机中修改程序调用指令,在指令末尾追加:
-graphicssystem raster
使用有序的数据
QCustomPlot的setData()函数默认会对传入的数据进行排序。如果数据已经有序,可以将该函数的alreadySorted参数设为true。
尽可能减少QCustomPlot内部数据转移的次数
QCustomPlot的setData()函数中涉及大量的数据转移,可以修改QCustomPlot的源代码实现对QCustomPlot数据存储区变量mData的直接访问。在qcustomplot.h中,找到QCPDataContainer类的定义,并在其public:成员中添加:
// access mData directly, see https://www.cnblogs.com/pied/p/5164000.html
QVector<DataType>* coreData() {return &mData;}
需要向QCustomPlot控件添加内容时,可以使用以下方式直接访问其数据存储区:
//Get a pointer of mData
QVector<QCPGraphData> * mData = ui->chrtPlot->graph(0)->data()->coreData();
//Read data
double dX = mData->at(iIndex)->key;
double dY = mData->at(iIndex)->value;
//Add data
mData->push_back(QCPGraphData(dX, dY));
参考文献
https://www.qcustomplot.com/documentation/performanceimprovement.html