使用QPainter绘制饼状图,并显示所占百分比

绘制饼状图qt就有现成的函数来用,要在相应部分的弧形里显示百分比就需要做一点处理。

做法就是在获取扇形二等分线的中点坐标,以这个中点坐标为中心的一个区域再绘制文字。

获取中点坐标使用三角函数即可,半径懂,角度也有,很容易就算出距离,再根据所在的象限添加符号就是坐标了

效果图:

使用QPainter绘制饼状图,并显示所占百分比_第1张图片

下面上代码

头文件

#include 
#include 
#include 

class ArcWidget : public QWidget
{
    Q_OBJECT

public:
    explicit ArcWidget(QWidget *parent = 0);
    ~ArcWidget();

protected:
    void paintEvent(QPaintEvent *e);

private:
    QString getPercentInt(const QString &percentStr);


private:
    QMap m_answerMap;
    QList m_numList;
    QList m_answerStrList;
    int m_nPeopleCount;
    qreal m_pi = 3.1415;

};

cpp文件

#include "arcwidget.h"

ArcWidget::ArcWidget(QWidget *parent)
    : QWidget(parent), m_nPeopleCount(0)
{
    this->resize(600, 600);

    m_answerMap.insert("A", 3);
    m_answerMap.insert("B", 5);
    m_answerMap.insert("C", 8);
    m_answerMap.insert("D", 2);

    m_answerStrList = m_answerMap.keys();
    m_numList = m_answerMap.values();
    foreach (int num, m_numList) {
        m_nPeopleCount += num;
    }
}

ArcWidget::~ArcWidget()
{

}

void ArcWidget::paintEvent(QPaintEvent *e)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::NoBrush);
//    painter.drawImage(this->rect(),m_bg);

    QRectF rect(-120, -120,
                (120 << 1), (120 << 1));
    QList colorList;

    painter.translate(220, 255);
    qreal startAngle = 0;
    foreach (int num, m_numList) {

        //生成随机颜色并过滤掉白色
        int colorR, colorG, colorB;
        while(1)
        {
            colorR = rand()%256;
            colorG = rand()%256;
            colorB = rand()%256;

            if(colorR == 255 && colorG == 255 && colorB == 255)
            {
                continue;
            }
            else
            {
                break;
            }
        }
        QColor color(colorR, colorG, colorB);
        colorList.append(color);

        painter.setPen(Qt::NoPen);
        painter.setBrush(QBrush(color));

        //该答案选项所占比例
        qreal percentNum = (qreal)num/(qreal)m_nPeopleCount;
        //所占比例对应的角度
        qreal arcLength = 360*percentNum;

        //画扇形
        QPainterPath path;
        path.arcTo(rect, startAngle, arcLength);

        //扇形二等分线的角度
        qreal middleAngle = startAngle + arcLength/2;
        qreal radianNum = 0;
        if(middleAngle >= 0 && middleAngle < 90)
        {
            radianNum = middleAngle*m_pi/180;
        }
        else if(middleAngle >= 90 && middleAngle < 180)
        {
            radianNum = (180 - middleAngle)*m_pi/180;
        }
        else if(middleAngle >= 180 && middleAngle < 270)
        {
            radianNum = (middleAngle - 180)*m_pi/180;
        }
        else if(middleAngle >= 270 && middleAngle < 360)
        {
            radianNum = (360 - middleAngle)*m_pi/180;
        }

        //二等分线的中点距原点的距离
        qreal textPosY = 60*sin(radianNum);
        qreal textPosX = 60*cos(radianNum);

        //根据二等分线所在的象限确定二等分线的中点坐标
        if(middleAngle >= 0 && middleAngle < 90)
        {
            textPosY = -textPosY;
        }
        else if(middleAngle >= 90 && middleAngle < 180)
        {
            textPosX = -textPosX;
            textPosY = -textPosY;
        }
        else if(middleAngle >= 180 && middleAngle < 270)
        {
            textPosX = -textPosX;
        }

        startAngle += arcLength;
        QString percentStr = QString::number(percentNum*100 + 0.5);
        percentStr = getPercentInt(percentStr) + "%";
        painter.drawPath(path);
        painter.setPen(QColor(Qt::white));
        painter.drawText(textPosX - 25, textPosY -10,
                         50, 20, Qt::AlignCenter, percentStr);

    }

    painter.setBrush(Qt::NoBrush);
    painter.setPen(QColor(0, 0, 0));
    painter.translate(-220, -255);

    //绘制右侧的标注栏
    QFont ft;
    ft.setPixelSize(15);
    painter.setFont(ft);
    int textStart = 140;
    foreach (QString answerStr, m_answerStrList) {
        painter.drawText(350, textStart,
                         40, 16,
                         Qt::AlignRight, answerStr);
        textStart += 30;
    }

    textStart = 143;
    painter.setPen(Qt::NoPen);
    foreach (QColor color, colorList) {
        painter.setBrush(QBrush(color));
        painter.drawRect(402, textStart, 15, 15);
        textStart += 30;
    }

    QWidget::paintEvent(e);
}

QString ArcWidget::getPercentInt(const QString &percentStr)
{
    QString percentIntStr;
    for(int i = 0;i < percentStr.size();++i)
    {
        if(percentStr.at(i) == '.')
        {
            break;
        }
        percentIntStr += percentStr.at(i);
    }

    return percentIntStr;
}

 
  

你可能感兴趣的:(Qt,Painter,饼状图)