Qt实现实时曲线

来源:互联网 发布:矩阵论教程 pdf 编辑:程序博客网 时间:2024/06/09 19:11

Qt实现曲线的方式有多种方式,第三方库也有不少,例如QtChart,QCustomPlot,Qwt,chartDirector或者利用js也可以实现。对于不用库的优缺点就不在这里说明了。本例子只是利用Qt的QPainter实现。可以支持4.x,5.x(3.x应该也可以没有测试)。
这里写图片描述
使用如下
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 <QWidget> include <QList> #include <QFont>  #include <QDateTime> #include "qmath.h"class CRealTimeLine : public QWidget{    Q_OBJECTpublic:    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<QColor> 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);    }}//画刻度Yindex = 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;

//////画YQPointF 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;

}

“`

原创粉丝点击