QT开发----绘制统计图

代码实现绘制折线图、饼状图等统计图表。

1. 折线图

  • 头文件添加声明语句:
    void paintEvent(QPaintEvent *ev);
  • 实现paintEvent函数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    void Zhex::paintEvent(QPaintEvent *e)
    {
    QPainter painter(this);
    // 设置反锯齿
    painter.setRenderHint(QPainter::Antialiasing);
    QFontMetrics metrics=painter.fontMetrics();//返回绘图工具的字体信息
    int textHeight=metrics.ascent()+metrics.descent();//字体高度
    int leftWidth=metrics.width(tr("9000"))+20;//获取”9000“的宽度
    int rightWidth=metrics.width(tr("月份"))+20;
    int width=this->size().width()-leftWidth-rightWidth-101;
    int height=this->size().height()-4*textHeight;
    //绘制外框,左上角在(0,0),宽为->size().width()-1,高为w->size().height()-1的矩形
    // painter.drawRect(0,0,w->size().width()-1,w->size().height()-1);
    //移动坐标系
    //painter.translate(101,105+343);
    //painter.scale(1,-1);
    int totalCount=9000;//默认y轴最大值9000
    int count=5;//分成5份
    float deltaX=width/12.0f;//x轴上每份的宽度(12个月)
    float deltaY=343/count;
    //画横坐标
    QFont font;
    font.setBold(true);
    painter.setFont(font);
    painter.setPen(Qt::black);
    painter.drawLine(101,448,101+637+100,448);
    painter.drawText(101+637+100,448+5,">");//绘制坐标轴箭头
    painter.drawText(101+637+115,448+5,tr("月份"));
    for(int i=1;i<=12;i++)
    {
    QString month=tr("%1 ").arg(i);
    int stringWidth=metrics.width(month);//获取刻度的宽度

    //绘制坐标刻度
    painter.drawLine(101+deltaX*i,448,101+deltaX*i,448+4);

    //绘制坐标处的月
    int monthX=101+deltaX*(i-1)+(deltaX-stringWidth/2);
    painter.drawText(monthX,textHeight+448,month);
    }
    //画纵坐标
    painter.drawLine(101,448,101,448-343);
    painter.drawText(101-7,448-343,tr("/\\"));//绘制坐标轴箭头
    painter.drawText(101-10,448-343-15,tr("次数"));
    QString value[5]={"1200","2400","3600","4800","6000"};
    for(int i=1;i<=count;i++)
    {
    //绘制坐标刻度
    painter.drawLine(101,448-i*deltaY,101+4,448-i*deltaY);
    //绘制坐标值
    painter.drawText(101-30,448-i*deltaY+5,value[i-1]);
    }
    //绘制折线图形
    float y[12]={448-343/5,448-98,448-113,448-130,448-179,448-201,448-220,448-109,448-120,448-39,448-97,448-80};
    for(int i=1;i<12;i++)
    {
    painter.setPen(QPen(QBrush(Qt::red), 5, Qt::SolidLine));
    painter.drawLine(101+deltaX*i,y[i-1],101+deltaX*(i+1),y[i]);
    }
    }

2. 饼状图

  • 头文件中添加声明语句:
    void paintEvent(QPaintEvent *ev);
  • cpp文件中实现 paintEvent函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    void bing::paintEvent( QPaintEvent* ev )
    {
    QPainter painter(this);
    // 去除画笔
    painter.setPen(Qt::NoPen);
    // 设置反锯齿
    painter.setRenderHint(QPainter::Antialiasing);
    //圆饼图
    QRectF rect_top(350.0, 160.0, 480.0, 200.0);
    // 底层圆面
    QRectF rect_bottom(350.0, 200.0, 480.0, 200.0);
    // 中间矩形
    QRectF rect_midd(350.0, 260.0, 480.0, 40.0);
    // 扇形起始角度
    int startAngle = 230 * 16;
    // 扇形覆盖范围
    int spanAngle = 60 * 8;

    painter.setBrush(QColor(Qt::darkBlue));
    // 绘制底层圆面
    painter.drawEllipse(rect_bottom);

    // 绘制中间矩形
    painter.drawRect(rect_midd);

    painter.setBrush(QColor(Qt::darkGreen));
    // 绘制底层扇形
    painter.drawPie(rect_bottom, startAngle, spanAngle);

    // 扇形的弦与弧的交点
    double pi = 3.1415926;
    double dx1 = rect_top.width() * 0.5 * cos(230*pi/180);
    double dy1 = rect_top.height() * 0.5 * sin(230 * pi / 180);
    double dx2 = rect_top.width() * 0.5 * cos(290 * pi / 180);
    double dy2 = rect_top.height() * 0.5 * sin(290 * pi / 180);
    // 求交点的坐标值
    QPointF posBackCenter = QPointF(rect_top.center());
    double dX1 = posBackCenter.x() + dx1 + 0.5;
    double dY1 = posBackCenter.y() - dy1 + 0.5;
    double dX2 = posBackCenter.x() + dx2 + 0.5;
    double dY2 = posBackCenter.y() - dy2 + 0.5;
    // 记录交点
    QPointF topLeft = QPointF(dX1, dY1);
    QPointF bottomRight = QPointF(dX2, dY2) + QPointF(0,40);
    QPointF bottomLeft = topLeft + QPointF(0,40);
    painter.setBrush(QColor(Qt::darkBlue));
    // 绘制连接扇形的区域
    QPolygonF path;
    path << topLeft << QPointF(dX2,dY2) << bottomRight << bottomLeft;
    painter.drawPolygon(path);
    painter.setBrush(QColor(Qt::darkGreen));
    // 绘制底层扇形
    painter.drawPie(rect_bottom, startAngle, spanAngle);
    // 绘制顶层圆面
    painter.setBrush(QColor(Qt::blue));
    painter.drawEllipse(rect_top);
    // 绘制顶层扇形
    painter.setBrush(QColor(Qt::green));
    painter.drawPie(rect_top, startAngle, spanAngle);
    QString temp="sddsd";
    painter.setBrush(QColor(Qt::black));
    QWidget::paintEvent(ev);
    }
  • 包含头文件:

    1
    2
    3
    4
    5
    6
    #include<QPainter>
    #include<QPaintEvent>
    #include<QtGui/QPainter>
    #include<iostream>
    #include<math.h>
    using namespace std;
写的还不错?那就来个红包吧!
0%