Qt画k线图

Qt画k线图

2019-09-02 12:18:38 小生无名 阅读数 141更多

分类专栏: QT

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/cqltbe131421/article/details/100176935

一个从excel读取数据到绘制成图标的控件,
609162385,
在这里插入图片描述

#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

  •  
  • 0
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值