赞
踩
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_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<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); } } //画刻度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;
}
“`
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。