一个从excel读取数据到绘制成图标的控件,

Qt画k线图_#include

#include "painterkwidget.h"
#include <QDebug>


PainterKWidget::PainterKWidget(QWidget *parent) : QWidget(parent)
{
background = QColor(255,255,255);

lineState = true;
dataSize = 0;
maxnum = 0;
mixnum = 0;
m_width = 0;
m_height = 0;

paint_width = 0;
paint_height = 0;

textHeight = 0;
leftWidth = 0;
rightWidth = 0;
coordinate = false;
space_w = 0;
space_h = 0;

count_x = 10; //坐标 分成10成
count_y = 10; //坐标 分成10成

range_x_start = 0;
range_y_start = 0;
range_x_end = 100;
range_y_end = 100;
}

void PainterKWidget::paintEvent(QPaintEvent *e)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing);
paintInit(&painter);
//绘制背景
drawBg(&painter);
//绘制标尺
drawAxis(&painter);
//绘制数据
drawData(&painter);
}

void PainterKWidget::drawBg(QPainter *painter)
{
painter->fillRect(this->rect(), background);
}

void PainterKWidget::drawData(QPainter *painter)
{
painter->setBrush(QColor(255,25,44));//设置填充
painter->translate(leftWidth+5,2.5 * textHeight);//移动
float mincurrent = 0;//计算当前最小值
float linecurrent = 0;//计算当前最小值
for(int i = 0; i < dataSize;i++){
if(points.at(i).y1 < points.at(i).y2){//这里的大于小于代表着方向
mincurrent = points.at(i).y2;
}else{
mincurrent = points.at(i).y1;
}//这里我们取的最大值
mincurrent -= range_y_start;
float currentHeight = points.at(i).h;//绘图高度
//这里就需要减去全数据最小值mixnum
painter->drawRect((float)i*space_w*2,paint_height - (mincurrent)*space_h,space_w,currentHeight*space_h);

//下面是划线
if(lineState == true){
linecurrent = (points.at(i).y2 + points.at(i).y1) / (float)2;
linecurrent -= range_y_start;
painter->drawLine((float)i*space_w*2,paint_height - (linecurrent)*space_h,((float)i+1)*space_w*2,paint_height - (linecurrent)*space_h);
}
}
}

void PainterKWidget::drawAxis(QPainter *painter)
{
QFontMetrics metrics = painter->fontMetrics();
// 绘制外框
painter->setBrush(QBrush("white"));
painter->drawRect(0, 0, this->size().width() -1, this->size().height() - 1);
// 移动坐标系
painter->translate(leftWidth, m_height - 1.5 * textHeight);
float totalCount_Y = range_y_end - range_y_start; // 默认值差
float totalCount_X = range_x_end - range_x_start; // 默认值差

float deltaX = paint_width / count_x; // x坐标上每分的宽度
float deltaY = (float)paint_height / count_y; // y坐标上每分的宽度
// 画横坐标
if(coordinate == false){
painter->drawLine(0, 0, paint_width, 0);
for (int i = 1; i <= totalCount_X; ++i) {
QString month = QString("%1").arg(QString::number(i * totalCount_X / count_x,'f',0));
float stringWidth = metrics.width(month);
// 绘制坐标刻度
painter->drawLine(deltaX * i, 0, deltaX * i, 4);
// 绘制坐标处的月
float monthX = deltaX * (i - 1) + ((deltaX - stringWidth));
painter->drawText(monthX, textHeight, month);
}
}else{
painter->drawLine(0, -paint_height, paint_width, -paint_height);
for (int i = 1; i <= totalCount_X; ++i) {
QString month = QString("%1").arg(QString::number(i * totalCount_X / count_x,'f',0));
float stringWidth = metrics.width(month);
// 绘制坐标刻度
painter->drawLine(deltaX * i, -paint_height, deltaX * i, -paint_height + 4);
// 绘制坐标处的月
float monthX = deltaX * (i - 1) + ((deltaX - stringWidth)) ;
painter->drawText(deltaX * i - 20, -paint_height - 4,month);
}
}

// 画纵坐标
painter->drawLine(0, 0, 0, -paint_height);
//画上面H
painter->drawText(-metrics.width(tr("(y)")),
-(deltaY * count_y + textHeight / 2 + metrics.descent()),
tr("H"));
//画刻度
for (int i = 1; i <= count_y; ++i) {
QString value = QString("%1").arg(QString::number(i * totalCount_Y / count_y + range_y_start,'f',0));
int stringWidth = metrics.width(value);
// 绘制坐标刻度
painter->drawLine(-4, -i * deltaY, 0, -i * deltaY);
// 绘制坐标值
painter->drawText(-stringWidth - 4, -(deltaY * i + textHeight / 2 - metrics.ascent()), value);
}
painter->resetTransform();
}

void PainterKWidget::resizeEvent(QResizeEvent *event)
{
m_width = this->width();
m_height = this->height();
}

void PainterKWidget::wheelEvent(QWheelEvent *event)
{

}

void PainterKWidget::mousePressEvent(QMouseEvent *event)
{

}

void PainterKWidget::mouseReleaseEvent(QMouseEvent *event)
{

}

void PainterKWidget::mouseMoveEvent(QMouseEvent *event)
{

}



void PainterKWidget::setCount_x(float value)
{
count_x = value;
update();
}

void PainterKWidget::setCount_y(float value)
{
count_y = value;
update();
}

void PainterKWidget::setRange_x(float value_start,float value_end)
{
range_x_start = value_start;
range_x_end = value_end;
update();
}

void PainterKWidget::setRange_y(float value_start,float value_end)
{
range_y_start = value_start;
range_y_end = value_end;
update();
}

void PainterKWidget::setCoordinate(bool value)
{
coordinate = value;
update();
}

void PainterKWidget::setLineState(bool value)
{
lineState = value;
update();
}
#ifndef PAINTERKWIDGET_H
#define PAINTERKWIDGET_H

#include <QWidget>
#include <QPainter>
#include <QColor>
#include <QWheelEvent>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QResizeEvent>
#include <QFontMetrics>

class PointParam{
public:
float y1;
float y2;
float center;
float h;
float w;
};

class PainterKWidget : public QWidget
{
Q_OBJECT
public:
explicit PainterKWidget(QWidget *parent = 0);

signals:

protected:
virtual void paintEvent(QPaintEvent *); //绘图事件
void drawBg(QPainter *painter); //画背景
void drawScaleLine(QPainter *painter); //画刻度
void drawData(QPainter *painter); //画数据
void drawAxis(QPainter *painter); //画z坐标
void paintInit(QPainter *painter); //数据初始
virtual void resizeEvent(QResizeEvent *event); //重写虚函数获取事件
virtual void wheelEvent(QWheelEvent *event); //重写虚函数获取事件
virtual void mousePressEvent(QMouseEvent *event)Q_DECL_OVERRIDE; //重写虚函数获取事件
virtual void mouseReleaseEvent(QMouseEvent *event)Q_DECL_OVERRIDE; //重写虚函数获取事件
virtual void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; //重写虚函数获取事件

public slots:
void setData(QVector<QPoint>);
void setCount_x(float);
void setCount_y(float);
void setRange_x(float,float);
void setRange_y(float,float);
void setCoordinate(bool );
void setLineState(bool );
private:
QVector<PointParam> points; //数据
QVector<QPoint> linePoints; //划线点
QColor background; //背景颜色

float dataSize; //数据大小
float maxnum; //最大值
float mixnum; //最小值
float disparity; //值差
float m_width; //控件宽度
float m_height; //控件高度

float paint_width; //绘图宽度
float paint_height; //绘图高度

float textHeight; //文本高度
float leftWidth; //左边宽度
float rightWidth; //右边宽度

float space_w; //间隔宽度
float space_h; //间隔高度

float count_x; //坐标 分成10层
float count_y; //坐标 分成10层

float range_x_start; //坐标 范围
float range_y_start; //坐标 范围
float range_x_end; //坐标 范围
float range_y_end; //坐标 范围

bool coordinate; //x坐标在上还是下
bool lineState; //划线状态
};

#endif // PAINTERKWIDGET_H