Qt实现实时曲线

Qt实现曲线的方式有多种方式,第三方库也有不少,例如QtChart,QCustomPlot,Qwt,chartDirector或者利用js也可以实现。对于不用库的优缺点就不在这里说明了。本例子只是利用Qt的QPainter实现。可以支持4.x,5.x(3.x应该也可以没有测试)。
Qt实现实时曲线_第1张图片
使用如下
m_line = new CRealTimeLine;
m_line->setDrawStartLeft(false);
m_line->addDataList(datalist);
QLinearGradient liner;
liner.setColorAt(0,QColor(“#9DCEFF”));
liner.setColorAt(1,QColor(“#FFFFFF”));
m_line->setInterval(5);
m_line->setBackColor(liner);
setCentralWidget(m_line);

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(5000);

头文件


ifndef CREALTIMELINE_H 

define CREALTIMELINE_H

 #include  
include 
 #include 
  #include 

 #include "qmath.h"

class CRealTimeLine : public QWidget
{
    Q_OBJECT

public:
    CRealTimeLine(QObject *parent = NULL);
    ~CRealTimeLine();

    void setXLabels(QStringList labellist);
    void setYLabels(QStringList labellist);
    void setDrawStartLeft(bool startleft = true); //默认从左侧
    void addDataList(QList<float> dlist);
    void addDataList(float value);
    void removeDatas(); //清除数据
    void setBackColor(QLinearGradient linegradent);
    void setLineColor(QColor color);
    void setMaxValue(int max);
    void setPrefixText(QString text);
    void setInterval(int interval);


private:
    void initdata();

private:
    QPainterPath drawGridding(); //网格
    QPainterPath drawRectPath(); //边框
    QPainterPath drawXYScalePath(); //x,y刻度
    void drawXLabel(QPainter &painter);
    void drawYLabel(QPainter &painter);
    QPainterPath drawLineLeftPath();  //左侧开始画线
    QPainterPath drawLineRigthPath();  //右侧开始画线
    QPainterPath drawBack(QPainter &painter);
    void drawText(QPainter &painter);  //默认最后一个值
    void drawLine(QPainter &painter);

private:
    void paintEvent( QPaintEvent * event );

private:
    QPointF m_originpoint;  //原点所在位置
    int m_griddingcount_x,m_griddingcount_y; //网格个数
    QStringList m_xlabellist,m_ylabellist;
    int m_count; //点的个数
    QList<float> m_datelist; //数据
    bool m_isstartleft; //画的方式,从左侧还是右侧 默认左侧
    int m_ymax,m_ymin;
    QList m_defaultcolors;
    QLinearGradient m_backlinegradent; //背景
    QColor m_linecolor;
    QString m_textstr;
    QDateTime m_olddateime;
    int m_interval;

};

endif // CREALTIMELINE_H

`cpp文件

include “crealtimeline.h”

include

CRealTimeLine::CRealTimeLine(QObject *parent)
//: QWidget(parent)
{
m_isstartleft = false;
m_count = 30*60; //默认30分钟的数据。一秒一个
m_ymax = 100;
m_ymin = 0;
m_defaultcolors.append(QColor(“red”));
m_defaultcolors.append(QColor(“blue”));
m_defaultcolors.append(QColor(“yellow”));
m_defaultcolors.append(QColor(“green”));
m_linecolor = QColor(“green”);
m_olddateime = QDateTime::currentDateTime();
m_interval = 1;
}

CRealTimeLine::~CRealTimeLine()
{

}
void CRealTimeLine::setXLabels( QStringList labellist )
{
m_xlabellist.clear();
m_xlabellist = labellist;
}

void CRealTimeLine::setYLabels( QStringList labellist )
{
m_ylabellist.clear();
m_ylabellist = labellist;
}

void CRealTimeLine::setDrawStartLeft( bool startleft /= true/ )
{
m_isstartleft = startleft;
}

void CRealTimeLine::addDataList( QList dlist )
{
for (int i = 0 ; i < dlist.count(); ++i)
{
addDataList(dlist.at(i));
}
}

void CRealTimeLine::addDataList( float value )
{
int tmp = (int)value+1;
if (tmp > m_ymax)
{
m_ymax = tmp*1.2;
}

m_ymin = qMin(m_ymin,tmp);
if (m_isstartleft)
{
    m_datelist.append(value);
    if (m_datelist.count() > m_count)
        m_datelist.removeFirst();
}
else
{
    m_datelist.prepend(value);

    if (m_datelist.count() > m_count)
        m_datelist.removeLast();
}

}

void CRealTimeLine::setMaxValue( int max )
{
m_ymax = max;
}

void CRealTimeLine::removeDatas()
{
m_datelist.clear();
}

void CRealTimeLine::setLineColor( QColor color )
{
m_linecolor = color;
}

void CRealTimeLine::setBackColor( QLinearGradient linegradent )
{
m_backlinegradent = linegradent;
m_backlinegradent.setStart(QPointF(width()/2,0));
m_backlinegradent.setFinalStop(QPointF(width()/2,height()));
}

void CRealTimeLine::setPrefixText( QString text )
{
m_textstr = text;
}

void CRealTimeLine::setInterval( int interval )
{
m_interval = interval;
}

void CRealTimeLine::initdata()
{
m_originpoint.setX(width()*0.1);
m_originpoint.setY(height()*0.9);
m_griddingcount_x = 20;
m_griddingcount_y = 10;

m_xlabellist.clear();
QDateTime curtime = QDateTime::currentDateTime();
int setp = QDateTime::currentDateTime().toTime_t()-m_olddateime.toTime_t();

if (setp > m_count )
{
    m_olddateime = m_olddateime.addSecs(m_interval);
}
if (m_isstartleft)
{
    QTime ctime = m_olddateime.time();
    for (int i = 0; i < 5; ++i)
    {
        QTime tmp = ctime.addSecs(i*6*60); //30分钟
        m_xlabellist.append(tmp.toString("hh:mm:ss"));
    }
}
else
{
    QTime ctime = QDateTime::currentDateTime().time();
    for (int i = 0; i < 5; ++i)
    {
        QTime tmp = ctime.addSecs(-i*6*60); //30分钟
        m_xlabellist.push_front(tmp.toString("hh:mm:ss"));
    }
}

m_ylabellist.clear();
float step = 1.0*(m_ymax - m_ymin)/10;
for (int i = 0; i < 11; ++i)
{
    m_ylabellist << QString("%1").arg(m_ymin + step*i);
}

}

void CRealTimeLine::paintEvent( QPaintEvent * event )
{
initdata();

QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setRenderHint(QPainter::TextAntialiasing, true);
painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
QFont font;
font.setPixelSize(11);
painter.setFont(font);

painter.save();
painter.setPen(QPen(Qt::lightGray));
painter.setBrush(m_backlinegradent);
painter.drawPath(drawBack(painter));
painter.restore();

drawText(painter);

painter.save();
//painter.setBrush(m_backlinegradent);
painter.drawPath(drawRectPath());
painter.restore();

painter.save();
QPen pen;
pen.setColor(Qt::lightGray);
pen.setStyle(Qt::DotLine);
painter.setPen(pen);
painter.drawPath(drawGridding());
painter.restore();


painter.drawPath(drawXYScalePath());
drawXLabel(painter);
drawYLabel(painter);

drawLine(painter);

}

QPainterPath CRealTimeLine::drawGridding()
{
//QPainter painter(this);
QPointF oldp(m_originpoint);
//画背景虚线
QPainterPath gridding_xypath;
oldp = m_originpoint;

int w = width()*0.8;
int h = height()*0.8;
float index = 1.0*w/m_griddingcount_x;
for (int i = 0; i < m_griddingcount_x; ++i)
{
    oldp.setX(oldp.x()+index);
    gridding_xypath.moveTo(oldp);
    gridding_xypath.lineTo(oldp.x(),oldp.y()-h);
}

oldp = m_originpoint;
index = 1.0*h/m_griddingcount_y;
for (int i = 0; i < m_griddingcount_y; ++i)
{
    oldp.setY(oldp.y() - index);
    gridding_xypath.moveTo(oldp);
    gridding_xypath.lineTo(oldp.x()+w,oldp.y());
}

return gridding_xypath;

}

QPainterPath CRealTimeLine::drawRectPath()
{
int w = width()*0.8;
int h = height()*0.8;
QPainterPath XYPathRect;
XYPathRect.addRect(m_originpoint.x(),m_originpoint.y()-h,w,h);
return XYPathRect;
}

QPainterPath CRealTimeLine::drawBack( QPainter &painter )
{
QPainterPath XYPathRect;
XYPathRect.addRect(0,0,width(),height());
return XYPathRect;
}

QPainterPath CRealTimeLine::drawXYScalePath()
{
int w = width()*0.8;
int h = height()*0.8;
QPainterPath XYPath;
//画刻度X
QPointF oldp(m_originpoint);

float index = 1.0*w/m_griddingcount_x;
int tickcount = 5;
for (int i = 0; i < m_griddingcount_x; ++i)
{
    QPointF tmppoint(oldp);
    float index_tmp = index/tickcount;

    tmppoint.setX(tmppoint.x()+index*i);
    for (int j = 0 ; j < tickcount ;j++)
    {
        QPointF p(tmppoint);
        int d = 0;
        if (j == 0)
            d = 2;

        p.setX(p.x()+index_tmp*j);
        XYPath.moveTo(p);
        p.setY(p.y() + 5+d);

        XYPath.lineTo(p);
    }
}

//画刻度Y
index = 1.0*h/m_griddingcount_y;
tickcount = 1;
for (int i = 0; i < m_griddingcount_y; ++i)
{
    QPointF tmppoint(oldp);
    float index_tmp = index/tickcount;
    tmppoint.setY(tmppoint.y()-index*i);
    for (int j = 0 ; j < tickcount ;j++)
    {
        QPointF p(tmppoint);
        int d = 0;
        if (j == 0)
            d = 2;
        p.setY(p.y() - index_tmp*j);
        XYPath.moveTo(p);
        p.setX(p.x() - 5-d);
        XYPath.lineTo(p);
        //p.setX(p.x() + 5);
    }
}

//if (m_y2_visable)
//{
//  oldp =m_originpoint;
//  oldp.setX(oldp.x()+m_length_x);
//  for (int i = 0; i < m_tickcount_y2; ++i)
//  {
//      QPointF p(oldp);
//      p.setY(p.y() - m_tick_y2_index*i);
//      XYPath.moveTo(p);
//      p.setX(p.x() + m_tick_xy);

//      XYPath.lineTo(p);

//  }
//}

return XYPath;

}

void CRealTimeLine::drawXLabel(QPainter &painter)
{
painter.save();
//////画X
if (m_xlabellist.isEmpty() ) return;
int w = width()*0.8;
//int h = height()*0.8;

QPointF oldp(m_originpoint);
int _height = 15;
int index = w/(m_xlabellist.count()-1);
for (int i = 0; i < m_xlabellist.count(); ++i)
{
    QString textstr = m_xlabellist.at(i);
    QPointF p(oldp);
    p.setY(p.y()+5);

    float x = p.x()+index*i-10;
    float y = p.y();

    QRectF rect_(x,y,textstr.length()*10,_height);
    painter.drawText(rect_, Qt::AlignTop, textstr);

}
painter.restore();

}

void CRealTimeLine::drawYLabel(QPainter &painter)
{
if (m_ylabellist.isEmpty() ) return;
//int w = width()*0.8;
int h = height()*0.8;

//////画Y
QPointF oldp(m_originpoint);
int _height = 15;
int index = h/(m_ylabellist.count()-1);
for (int i = 0; i < m_ylabellist.count(); ++i)
{
    QString textstr = m_ylabellist.at(i);
    QPointF p(oldp);

    float x = p.x()-_height*textstr.length()-10;
    float y = p.y()-index*i-10;

    QRectF rect_(x,y,_height*textstr.length(),20);

    painter.drawText(rect_, Qt::AlignRight, textstr);
}
painter.restore();

}

void CRealTimeLine::drawText( QPainter &painter )
{
painter.save();
QFont font;
font.setPixelSize(12);
painter.setFont(font);
int w = width()*0.1;
int h = height()*0.02;
QString str;
if (m_isstartleft)
{
if (m_datelist.count() > 0)
{
QString tstr = QString::number(m_datelist.last(),’f’,2);
str = QString(“%1%2”).arg(m_textstr).arg(tstr);
}
else
str = m_textstr;
}
else
{

    if (m_datelist.count() > 0)
    {
        QString tstr = QString::number(m_datelist.first(),'f',2);
        str = QString("%1%2").arg(m_textstr).arg(tstr);
    }
    else
        str = m_textstr;
}
QRectF rect(w,h,w*8,h*4);
painter.drawText(rect, Qt::AlignLeft, str);
painter.restore();

}

void CRealTimeLine::drawLine(QPainter &painter)
{

painter.save();
QColor color = m_linecolor;
if (m_isstartleft)  //左侧开始
{
    painter.setPen(QPen(color));
    painter.drawPath(drawLineLeftPath());
}
else
{
    painter.setPen(QPen(color));
    painter.drawPath(drawLineRigthPath());
}
painter.restore();

}

QPainterPath CRealTimeLine::drawLineLeftPath()
{
QPainterPath linepath;
int w = width()*0.8;
int h = height()*0.8;
QPointF oldp(m_originpoint);
float step = 1.0*w/m_count;
float ystep = 1.0*h/(m_ymax-m_ymin);
if (m_datelist.isEmpty()) return linepath;
if (m_datelist.count() == 1)
{
linepath.moveTo(m_originpoint.x(),m_originpoint.y() - ystep*m_datelist.at(0));
linepath.lineTo(m_originpoint.x()+5,m_originpoint.y() -ystep*m_datelist.at(0));
return linepath;
}
for (int i = 0 ; i < m_datelist.count()-1; ++i)
{
linepath.moveTo(m_originpoint.x()+step*i,m_originpoint.y() - ystep*m_datelist.at(i));
linepath.lineTo(m_originpoint.x()+step*i+step,m_originpoint.y() -ystep*m_datelist.at(i+1));
}
return linepath;
}

QPainterPath CRealTimeLine::drawLineRigthPath()
{
QPainterPath linepath;
float w = width()*0.8;
int h = height()*0.8;

float step = 1.0*w/m_count;
float ystep = 1.0*h/(m_ymax-m_ymin);
if (m_datelist.isEmpty()) return linepath;
if (m_datelist.count() == 1)
{
    linepath.moveTo(m_originpoint.x()+w,m_originpoint.y() - ystep*m_datelist.at(0));
    linepath.lineTo(m_originpoint.x()+w-5,m_originpoint.y() -ystep*m_datelist.at(0));
    return linepath;
}
//QPointF oldp(m_originpoint);
//oldp.setX(m_originpoint.x()+w-step*m_datelist.count());
for (int i = m_datelist.count()-1 ; i > 0; --i)
{
    linepath.moveTo(m_originpoint.x()+w-step*i,m_originpoint.y() - ystep*m_datelist.at(i));
    linepath.lineTo(m_originpoint.x()+w-step*i+step,m_originpoint.y() -ystep*m_datelist.at(i-1));   
}


return linepath;

}

“`

你可能感兴趣的:(Qt)