提示:Qt,QCustomPlot,C++


前言

提示:QCustomPlot、QCPLayer、QCPItemTracer

  简单介绍QCustomPlot、QCPLayer、QCPItemTracer,并分析游标移动时带来的延迟卡顿问题,并提出解决方案。

使用版本:
QCustomPlot 2.1.1


提示:以下是本篇文章正文内容,下面案例可供参考

一、QCustomPlot、QCPLayer、QCPItemTracer

QCustomPlot
QCPLayer
QCPItemTracer

二、当游标移动时绘制所有图层带来的延迟卡顿问题

class QCPWidget : public QWidget
{
    Q_OBJECT

public:
    explicit QCPWidget(QWidget *parent = nullptr) : QWidget(parent)
    {
        m_qcp = new QCustomPlot(this);
        m_tracer = new QCPItemTracer(m_qcp);
        
        connect(m_qcp, &QCustomPlot::mouseMove, this, &QCPWidget::onMouseMoved);
    }

private:
    QCustomPlot *m_qcp;
    QCPItemTracer *m_tracer;

private slots:
    void onMouseMoved(QMouseEvent *event)
    {
        /*
         * Calculate and move the 'm_tracer' based on the 'event'
        */
        m_qcp->replot();    // Replot the 'm_qcp'
    }
};

  上述的方法是在鼠标移动的过程中调用m_qcp->replot();来重绘整个qcp。如果在这个qcp上具有非常复杂和繁多的graph或者QCPAbstractItem等等时,m_qcp->replot();的操作会重绘上面所有的内容,势必会导致延迟和卡顿的问题。

三、解决方案分析

  首先,我们来分析QCPLayer。qcp的初始图层分为6个:“background”, “grid”, “main”, “axes”, “legend” and “overlay”。
QCPLayer

  上图是我根据官方的文档绘制的简易图层,从图中能看出graph和QCPAbstractItem会默认绘制在各自的图层上。
  其次,m_qcp->replot();的这个操作是将所有的QCPLayer进行重绘。
  最后,QCPLayer有一个属性QCPLayer::LayerMode,当设置模式(QCPLayer::setMode)到QCPLayer::lmBuffered。QCustomPlot会专门为该层分配了专用的绘制缓冲区,并允许使用QCPLayer::replot对其进行单独重新绘制。
  至此,方案已经基本成型,我们只需要将QCPItemTracer设置到一个独立的图层,并设置模式为QCPLayer::lmBuffered,然后调用该独立图层的QCPLayer::replot就可以单独对游标图层进行重绘。

四、解决方案

class QCPWidget : public QWidget
{
    Q_OBJECT

public:
    explicit QCPWidget(QWidget *parent = nullptr) : QWidget(parent)
    {
        m_qcp = new QCustomPlot(this);
        m_tracer = new QCPItemTracer(m_qcp);

        m_qcp->addLayer("tracer");
        m_qcp->layer("tracer")->setMode(QCPLayer::LayerMode::lmBuffered);
        m_tracer->setLayer(m_qcp->layer("tracer"));

        connect(m_qcp, &QCustomPlot::mouseMove, this, &QCPWidget::onMouseMoved);
    }

private:
    QCustomPlot *m_qcp;
    QCPItemTracer *m_tracer;

private slots:
    void onMouseMoved(QMouseEvent *event)
    {
        /*
         * Calculate and move the 'm_tracer' based on the 'event'
        */
        m_tracer->layer()->replot();    // Replot the 'Tracer' layer
    }
};

总结

  文章简单介绍了QCustomPlot、QCPLayer、QCPItemTracer,并阐述了通过分图层的方式绘制QCPItemTracer的方案来解决绘制所有图层带来的延迟卡顿问题。这个方案也可以拓展到类似如游标这样实时性高或定期需更新的组件,来分离这类组件与其他图层,以达到单独更新这些组件而不重绘所有图层的目的。
  感谢您的仔细阅读,如果发现文章中的不足之处,您可以给予指正和建议,这是对我莫大的提升,再次感谢!

Logo

鸿蒙生态一站式服务平台。

更多推荐