Qt自定义控件6:自定义饼状图

Qt自定义控件6:自定义饼状图

先看效果图:
在这里插入图片描述

思路:在类中定义一个Part用来存储每一个图中部分的属性,包含 占比,颜色,part的文字。使用qlist存储多个part,给外界提供addPart(。。。)方法,画图时直接根据占比得到角度画圆弧。

效果图是在调用时添加了4个分别占25%的part。

关键代码:CMPerChart1.cpp

void CMPerChart1::paintEvent(QPaintEvent *event){
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.translate(width / 2, height / 2);
    painter.scale(side / 200.0, side / 200.0);

    drawFrame(&painter);
    drawChartName(&painter); //画图的名称
    if(ltPart.count()>0){
        drawPart(&painter);
        drawPartText(&painter);//在每个部分中画上文字
    }
}

void CMPerChart1::drawFrame(QPainter *painter){
    painter->setPen(Qt::NoPen);
    //画外圈边缘及外圈
    int outSideRadius = outRadius+outSide;
    painter->save();
    painter->setBrush(QBrush(QColor("#E4E4E4")));
    painter->drawEllipse(-outSideRadius,-outSideRadius,2*outSideRadius,2*outSideRadius);
    painter->restore();

    painter->save();
    painter->setBrush(QBrush(QColor("#FFFFFF")));
    painter->drawEllipse(-outRadius,-outRadius,2*outRadius,2*outRadius);
    painter->restore();


    //画内圈边缘及内圈
    int inSideRadius = inSide+inRadius;
    painter->save();
    painter->setBrush(QBrush(QColor("#E4E4E4")));
    painter->drawEllipse(-inSideRadius,-inSideRadius,2*inSideRadius,2*inSideRadius);
    painter->restore();

    painter->save();
    painter->setBrush(QBrush(QColor("#FFFFFF")));
    painter->drawEllipse(-inRadius,-inRadius,2*inRadius,2*inRadius);
    painter->restore();
}

void CMPerChart1::drawChartName(QPainter *painter){
    int textRadius = inRadius-textSide;
    painter->save();
    painter->setPen(QPen(Qt::black));
    QFont font = painter->font();
    font.setPixelSize(8);
    painter->setFont(font);
    QRectF rect(-textRadius,-textRadius,2*textRadius,2*textRadius);
    painter->drawText(rect,Qt::AlignCenter,chartname);
    painter->restore();
}

void CMPerChart1::drawPart(QPainter *painter){
    for(Part part : ltPart){
        int out = outRadius;
        int in = inRadius+inSide;
        int adjust = out-in;

        //画part圆弧
        painter->save();
        painter->setBrush(part.partColor);

        QRectF rect(-out, -out, out << 1, out << 1);
        QPainterPath path;
        path.arcTo(rect, part.partRStart, part.partPercent*360);

        QPainterPath subPath;
        subPath.addEllipse(rect.adjusted(adjust, adjust, -adjust, -adjust));

        path -= subPath;

        painter->setPen(Qt::NoPen);
        painter->drawPath(path);

        painter->restore();

//        //画part的text
//        painter->save();
//        painter->setPen(Qt::black);

//        int textRaidus = (out+in)/2;
//        float textRange  =(part.partRStart+part.partREnd)/2;
//        float x = textRaidus*qCos(textRange);
//        float y = textRaidus*qSin(textRange);
//        qDebug()<<textRange<<","<<x<<","<<y;

//        painter->drawText(x-12,y,part.partname);

//        painter->restore();

    }
}

void CMPerChart1::drawPartText(QPainter *painter){
    int out = outRadius;
    int in = inRadius+inSide;
    for(Part part : ltPart){
        //画part的text
        painter->save();
        painter->setPen(Qt::black);

        int textRaidus = (out+in)/2;
        float textRange  =(part.partRStart+part.partREnd)/2;
        float x = textRaidus*qCos(textRange/180*3.14);
        float y = -textRaidus*qSin(textRange/180*3.14);
        qDebug()<<textRange<<","<<x<<","<<y;

        painter->drawText(x-15,y,part.partname);

        painter->restore();
    }

}

void CMPerChart1::drawPartSpacer(QPainter *painter){

}

void CMPerChart1::addPart(QString partname,QColor partColor,float partPercent){
    Part newPart;
    newPart.partname = partname;
    newPart.partColor = partColor;
    newPart.partPercent = partPercent;

    int count = ltPart.count();
    if(count>0){
        newPart.partRStart = ltPart.at(count-1).partREnd;
    }else{
        newPart.partRStart =0;
    }

    float range = partPercent*360;
    newPart.partREnd = newPart.partRStart+range;
    if(newPart.partREnd>360){
        qDebug()<<"range>360,the percent is wrong";
    }
    ltPart.append(newPart);
    update();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

制造垃圾代码的垃圾coder一个

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值