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嚇着了.

 

 

 

//


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM