前面也写了一个关于折线的,可是那个太...,暑假没事在家又弄了一个,希望它能够有一点可适应性和扩展性。
下面是代码实现
/*************************************************
折线图绘制
author 周翔
2012-8-14
*************************************************/
#ifndef LINEGRAPHWIDGET_H
#define LINEGRAPHWIDGET_H
#include <QWidget>
#include <QPen>
#include <QPainter>
#include <QResizeEvent>
//#include <QDebug>
#include <QTimer>
struct point
{
int x;
int y;
};
class LineGraphWidget : public QWidget
{
Q_OBJECT
public:
//mix和max为折线的y轴的数据范围
explicit LineGraphWidget(int mix, int max,QWidget *parent = 0);
void setSingleUnitX(const int &value) {singleUnitX = value;}//设置x轴的一个单位占多少个像素,默认10
//支持定时器定时更新
void startUpdataTimer(int msecond);
void stopUpdataTimer();
signals:
//支持实时更新
void newDataCome();//有新数据到来时发出的折线图更新信号
public slots:
void showData(const int &data);//接受来之外部的数据
protected:
void paintEvent(QPaintEvent *);
void resizeEvent(QResizeEvent *e);
private:
QList<int> xList;
QList<int> yList;
int Counter;
//窗口的长和宽
int widgetX;
int widgetY;
//折线图的显示范围
int rangeMin;
int rangeMax;
//根据窗口和范围得出的单位长,x轴,y轴
int singleUnitX;
int singleUnitY;
//根据窗口得出的多少个单位,x轴,y轴
int sumUnitX;
int sumUnitY;
point basePoint;//折线图的原点
point xAxisEndPoint;//X轴的终点
point yAxisEndPoint;//Y轴的终点
QTimer *timer;
void getSumUnitX();
void getSingleUnitY();
void initGraph();
};
#endif // LINEGRAPHWIDGET_H
#include "linegraphwidget.h"
LineGraphWidget::LineGraphWidget(int mix, int max, QWidget *parent) :
QWidget(parent),
rangeMin(mix),
rangeMax(max),
singleUnitX(10),
timer(NULL)
{
connect(this,SIGNAL(newDataCome()),this,SLOT(update()));
}
void LineGraphWidget::paintEvent(QPaintEvent *)
{
int i;
int a,b,c,d;
Counter = 0;
QPixmap pix(widgetX,widgetY);
QPainter painter(&pix);
pix.fill(Qt::white);
QPen pen;
pen.setBrush(Qt::darkGreen);
painter.setPen(pen);
QPen pen1;
pen1.setBrush(Qt::black);
painter.setRenderHint(QPainter::Antialiasing);
for(i = 0;i < sumUnitX; ++i) {
a = basePoint.x + i*singleUnitX;
b = basePoint.y;
c= a;
d = yAxisEndPoint.y;
painter.drawLine(a,b,c,d);
}
for(i = 0; i < sumUnitY+1; ++i) {
a = basePoint.x;
b = basePoint.y - singleUnitY*i;
c = xAxisEndPoint.x;
d = b;
painter.drawLine(a,b,c,d);
}
painter.setPen(pen1);
for (i = 0;i < (sumUnitY/2+1);++i) {
QRectF rectF(0,basePoint.y - singleUnitY*i*2 - 5,basePoint.x,(widgetY - basePoint.y)/3);
painter.drawText(rectF,Qt::AlignCenter,QString::number(rangeMin+i*20));
}
for (i = 0;i < sumUnitX/5;++i) {
QRectF rectF(basePoint.x+singleUnitX*(5*i+3),basePoint.y,singleUnitX*4,widgetY-basePoint.y);
painter.drawText(rectF,Qt::AlignCenter,QString::number(5*(i+1)*singleUnitX));
}
int size = xList.size();
while(Counter < (size -1)) {
painter.drawLine(basePoint.x + xList.value(Counter)*singleUnitX,
basePoint.y - ((yList.value(Counter) - rangeMin)/10.0)*singleUnitY,
basePoint.x + xList.value(Counter + 1)*singleUnitX,
basePoint.y - ((yList.value(Counter + 1) - rangeMin)/10.0)*singleUnitY);
Counter++;
}
painter.end();
painter.begin(this);
painter.drawPixmap(0,0,pix);
painter.end();
Counter = 0;
}
void LineGraphWidget::resizeEvent(QResizeEvent * e)
{
if (e->oldSize() != size()) {
initGraph();
}
}
void LineGraphWidget::showData(const int &data)
{
//这里还要进行相关的数据正确性检测,不能超过图的范围
if (data > rangeMax || data < rangeMin) {
return;
}
int xsize = xList.size();
int yValue = data;
if (xsize == sumUnitX) {
xList.clear();
yList.clear();
xsize = xList.length();
}
if (xsize >= 1) {
xList.insert(xsize,xsize);
yList.insert(xsize,yValue);
emit newDataCome();
}
else {
xList.insert(xsize,xsize);
yList.insert(xsize,yValue);
}
}
void LineGraphWidget::getSumUnitX()
{
if ((static_cast<int>(widgetX*0.85))%singleUnitX == 0){
sumUnitX = (static_cast<int>(widgetX*0.85))/singleUnitX;
}
else {
sumUnitX = (static_cast<int>(widgetX*0.85))/singleUnitX + 1;
}
}
void LineGraphWidget::getSingleUnitY()
{
int range = rangeMax - rangeMin;
if (range == 0) {
sumUnitY = range/10 + 1;
}
else {
sumUnitY = range/10 + 2;
}
singleUnitY = (static_cast<int>(widgetY*0.85))/sumUnitY;
}
void LineGraphWidget::initGraph()
{
widgetX = size().width();
widgetY = size().height();
basePoint.x = static_cast<int>(widgetX*0.1);
basePoint.y = static_cast<int>(widgetY*0.9);
yAxisEndPoint.x = basePoint.x;
yAxisEndPoint.y = static_cast<int>(widgetY*0.05);
xAxisEndPoint.x = static_cast<int>(widgetX*0.95);
xAxisEndPoint.y = basePoint.y;
getSumUnitX();
getSingleUnitY();
}
void LineGraphWidget::startUpdataTimer(int msecond)
{
if (timer != NULL) {
if (timer->isActive()) {
timer->stop();
}
delete timer;
}
disconnect(SIGNAL(newDataCome()));
timer = new QTimer;
connect(timer,SIGNAL(timeout()),this,SLOT(update()));
timer->start(msecond);
}
void LineGraphWidget::stopUpdataTimer()
{
if (timer == NULL) {
}
else {
timer->stop();
delete timer;
}
}
这篇博客还是去年暑假写的,下面几位仁兄,纠结与main函数怎么写,我很是....,我认为这不是问题。
还是我把代码注释一下吧
/*************************************************
折线图绘制
author 周翔
2012-8-14
对外提供接口
void showData(int data);接受外部的折线数据
void setSingleUnitX(const int &value);设置x轴的单位像素
void startUpdataTimer(int msecond);定时器更新折线图
void stopUpdataTimer();关闭定时器
*************************************************/
#ifndef LINEGRAPHWIDGET_H
#define LINEGRAPHWIDGET_H
#include <QWidget>
#include <QPen>
#include <QPainter>
#include <QResizeEvent>
//#include <QDebug>
#include <QTimer>
struct point
{
int x;
int y;
};
class LineGraphWidget : public QWidget
{
Q_OBJECT
public:
//mix和max为折线的y轴的数据范围
explicit LineGraphWidget(int min, int max, QWidget *parent = 0);
void setSingleUnitX(const int &value) {singleUnitX = value;}//设置x轴的一个单位占多少个像素,默认10
//支持定时器定时更新
void startUpdataTimer(int msecond);
void stopUpdataTimer();
signals:
//支持实时更新
void newDataCome();//有新数据到来时发出的折线图更新信号
public slots:
/**
* @brief showData
* @param adress 地址
* @param _data 数据
*/
void showData(const QString& adress,int _data);//接受来之外部的数据
/**
* @brief slt_showData 接受外部数据
* @param name 设备名
* @param _data 数据
*/
void slt_showData(ushort name,int _data);
protected:
void paintEvent(QPaintEvent *);
void resizeEvent(QResizeEvent *e);
private:
QString m_currentNodeAdress;//当前显示的节点的地址
ushort m_currentNodeName;//当前节点的设备名
QList<int> xList;
QList<int> yList;
int Counter;
//窗口的长和宽
int widgetX;
int widgetY;
//折线图的显示范围
int rangeMin;
int rangeMax;
//根据窗口和范围得出的单位长,x轴,y轴
int singleUnitX;
int singleUnitY;
//根据窗口得出的多少个单位,x轴,y轴
int sumUnitX;
int sumUnitY;
point basePoint;//折线图的原点
point xAxisEndPoint;//X轴的终点
point yAxisEndPoint;//Y轴的终点
QTimer *timer;
void getSumUnitX();
void getSingleUnitY();
void initGraph();
void flush();//数据传入的节点不是现在的当前的节点的时候,刷新画面,清除所有的值
};
#endif // LINEGRAPHWIDGET_H