qt 使用qwt绘制波形,一个点一个点绘制,QwtPlotDirectPainter的使用,

使用  QwtPlotDirectPainter 可以一次性只绘制一个点,对于有大量快速绘图需要的地方来说,不需要使用replot,重新渲染那么多点,可以有效降低cpu使用

 头文件

#include <qmath.h>
#include <QVector>
#include <QPointF>
#include <qwt_plot_canvas.h>
#include <qwt_plot_layout.h>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_plot_marker.h>
#include <qwt_plot_grid.h>
#include <qwt_plot_magnifier.h>
#include <qwt_plot_panner.h>
#include <qwt_legend.h>
#include <qwt_plot_directpainter.h>
#include <qwt_series_data.h>
#include <qwt_symbol.h>
#include <qwt_interval.h>

一个存放数据的类

class CurveData: public QwtArraySeriesData<QPointF>
{
public:
    CurveData()
    {
    }

    virtual QRectF boundingRect() const
    {
        if ( d_boundingRect.width() < 0.0 )
            d_boundingRect = qwtBoundingRect( *this );

        return d_boundingRect;
    }

    inline void append( const QPointF &point )
    {
        d_samples.append(point);
        if(point.y()<=miny) miny = point.y();
        if(point.y()>=maxy) maxy = point.y();
    }

    void clear()
    {
        d_samples.clear();
        d_samples.squeeze();
        d_boundingRect = QRectF( 0.0, 0.0, -1.0, -1.0 );
    }
//    size_t size(){
//        return d_samples.size();
//    }
public:
    double miny = 0;
    double maxy = 1;

};

 

 

全局变量

    QwtPlotCurve *d_curve;                  // 画笔
    QwtPlotDirectPainter *d_directPainter;  //不用replot的绘图
    CurveData *curveData = nullptr;         // 用于保存数据
QwtInterval d_interval; // y轴最大值,最小值
 

初始化 

 

d_directPainter = new QwtPlotDirectPainter();//不重画的添加点
        QwtPlotCanvas *canvas1 = new QwtPlotCanvas();
        canvas1->setPaintAttribute( QwtPlotCanvas::BackingStore, false );//一种优化方式
        canvas1->setBorderRadius( 5 );//画布圆角
        if ( canvas1->testPaintAttribute( QwtPlotCanvas::BackingStore ) ) {
            canvas1->setAttribute( Qt::WA_PaintOnScreen, true );
            canvas1->setAttribute( Qt::WA_NoSystemBackground, true );
        }
        QPalette pal = canvas1->palette();
        pal.setColor( QPalette::WindowText, Qt::green );
        canvas1->setPalette(pal);
        ui->qwtPlot->setAutoReplot(false);
        ui->qwtPlot->setCanvas(canvas1);
        ui->qwtPlot->plotLayout()->setAlignCanvasToScales(true);

        //加入网格
        QwtPlotGrid* grid = new QwtPlotGrid();
        //grid->setPen(QColor(64,64,128,100),0.5);
        grid->setPen( Qt::gray, 0.0, Qt::DotLine );
        grid->enableX( true );
        grid->enableY( true );
        grid->attach(ui->qwtPlot);

        //设置 坐标轴范围,坐标轴标题
        ui->qwtPlot->setAxisScale(QwtPlot::xBottom,0,120,20);
        d_interval.setMaxValue(3500);
        d_interval.setMinValue(0);
        ui->qwtPlot->setAxisScale(QwtPlot::yLeft,d_interval.minValue(),d_interval.maxValue());
        ui->qwtPlot->setAxisTitle(QwtPlot::yLeft,QObject::trUtf8("Temporature->"));
        ui->qwtPlot->setAxisTitle(QwtPlot::xBottom,QObject::trUtf8("Time[s]->"));
        ui->qwtPlot->setTitle(QObject::trUtf8("Teasink"));

        //绘制标记线,y轴在0绘制直线  x轴在中间绘制直线
        //QwtPlotMarker *d_origin = new QwtPlotMarker();
        //d_origin->setLineStyle( QwtPlotMarker::Cross );
        //d_origin->setValue( d_interval.minValue() + d_interval.width() / 2.0, 0.0 );
        //d_origin->setLinePen( Qt::gray, 0.0, Qt::DashLine );
        //d_origin->attach(ui->qwtPlot);

        //画笔,用来绘制点
        d_curve = new QwtPlotCurve();
        d_curve->setStyle( QwtPlotCurve::Lines );//线条
        d_curve->setPen( QColor(0,255,0),1.5,Qt::SolidLine );//设置画笔颜色
        d_curve->setRenderHint( QwtPlotItem::RenderAntialiased, true );//Toggle an render hint//渲染
        d_curve->setPaintAttribute( QwtPlotCurve::ClipPolygons, false );//关闭,这个优化(点超过可见区域,需要绘制出来)
        curveData = new CurveData();
        d_curve->setData( curveData );//数据列表 QwtSeriesData<QPointF>
        d_curve->attach( ui->qwtPlot );

 

清空数据的操作    注意    不能使用  ui->qwtPlot->detachItems();因为这个操作会删除 d_curve

                curveData->clear();
                //ui->qwtPlot->detachItems();
                ui->qwtPlot->replot();
                ui->qwtPlot->show();

 

绘图 注意replot 不能太频繁,因此初始化范围时候最好就设置好范围

        int datatemporature = msg.mid(8,2).toInt(nullptr,16);
        datatemporature += msg.mid(10,2).toInt(nullptr,16)*256;

        QPointF point;
        point.setX((curveData->size()+1)*0.1);
        point.setY(datatemporature*1.0);
        curveData->append(point);
//一次只绘制一个点
        d_directPainter->drawSeries( d_curve, curveData->size()-2, curveData->size()-1 );
        int flagreplot = 0;
        if(curveData->miny<d_interval.minValue()){
            d_interval.setMinValue(curveData->miny-curveData->miny*0.15);
            flagreplot = 1;
        }
        if(curveData->maxy>d_interval.maxValue()){
            d_interval.setMaxValue(curveData->maxy+curveData->maxy*0.15);
            flagreplot = 1;
        }
        if(flagreplot>0){
            ui->qwtPlot->setAxisScale(QwtPlot::yLeft,d_interval.minValue(),d_interval.maxValue());
            ui->qwtPlot->replot();
        }

总结,关键点是初始化,绘图这一点也有区别,不要被官方的demo吓着了.

 

 

 

//

上一篇:椭圆曲率算法不同曲线的安全性


下一篇:成功解决ModuleNotFoundError: No module named ‘sklearn.learning_curve‘