Qt4.8.5以上版本绘制饼图

运行效果:

源码如下:

#ifndef PIE_H_
#define PIE_H_

#include <QtWidgets/QWidget>
#include "ui_pie.h"
class Pie : public QWidget
{
    Q_OBJECT

public:
    explicit Pie(QWidget *parent = Q_NULLPTR);
    ~Pie();

private:
    Ui::PieClass ui;
public:
    void paintEvent(QPaintEvent *);
    QString getPercentInt(const QString &percentStr);
    void leaveEvent(QEvent *);
    void enterEvent(QEvent *);
    void initPieNum();


private:
    QMap<QString, int> m_answerMap;
    QList<int> m_numList;
    QList<QString> m_answerStrList;
    int m_nPeopleCount;
    qreal m_pi = 3.1415;
};

#endif // ! PIE_H_

 

.cpp文件

#include "pie.h"
#include <QPainter>
#include <QLabel>
#include <QFont>
#include <QDebug>
#include <QTextCodec>

Pie::Pie(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    this->resize(700, 600);
    initPieNum();
}

Pie::~Pie()
{
}

void Pie::initPieNum()
{
    m_answerMap.insert("A", 3);
    m_answerMap.insert("B", 5);
    m_answerMap.insert("C", 8);
    m_answerMap.insert("D", 2);
    m_answerMap.insert("E", 7);

    m_answerStrList = m_answerMap.keys();
    m_numList = m_answerMap.values();
    foreach(int num, m_numList)
    {
        m_nPeopleCount += num;
    }
}
void Pie::paintEvent(QPaintEvent * e)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setPen(Qt::NoPen);
    painter.setBrush(Qt::NoBrush);

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

    /*圆的中心位置*/
    //painter.translate(220, 255);
    painter.translate(300, 300);
    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);
    //绘制右侧的标注栏
    int textStart = 300;
    QFont ft;
    ft.setPixelSize(15);
    painter.setFont(ft);

    foreach(QString answerStr, m_answerStrList)
    {
        painter.drawText(465, textStart, 20, 16, Qt::AlignRight, answerStr);
        textStart += 30;
    }
    textStart = 303;
    painter.setPen(Qt::NoPen);
    foreach(QColor color, colorList) {
        painter.setBrush(QBrush(color));
        painter.drawRect(450, textStart, 15, 15);
        textStart += 30;
    }
    QWidget::paintEvent(e);
}


QString Pie::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;
}
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值