QCustomPlot性能提升

一个嵌入式项目,项目需要使用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

https://www.cnblogs.com/pied/p/5164000.html

https://blog.csdn.net/qing666888/article/details/104015959

it
除非特别注明,本页内容采用以下授权方式: Creative Commons Attribution-ShareAlike 3.0 License