1、继承QWidget创建一个hnPieChart类,头文件如下:
#ifndef HNPIECHART_H
#define HNPIECHART_H
#include <QWidget>
#include "ui_hnPieChart.h"
class hnPieChart : public QWidget
{
Q_OBJECT
public:
hnPieChart(QWidget *parent = 0);
~hnPieChart();
public:
void ClearPieChart();//清除饼图
void SetChartTitle(const QString& titleName,QFont titleFont,QColor titleColor);//设置饼图标题名称、字体、颜色
void AddComponentToChart(const QString& name, int Num, QColor color,QFont legendFont,QColor legendColor);//设置饼图组成部分的名称、数量、颜色以及图例的字体、颜色。
private:
void paintEvent(QPaintEvent *event);//重载虚函数,实时重绘
void CalculatePercentage();//计算各组成部分的百分比
public slots:
void DrawPieChart();//绘制饼图的函数
private:
Ui::hnPieChart ui;
int m_NumOfComponent;//饼图组成部分的数量
QVector<QString> m_componentNameVec;//饼图组成部分的的名称
QVector<int> m_componentNumberVec;//饼图组成部分的数量
QVector<QColor> m_componentColorVec;//饼图组成部分的颜色
QVector<double> m_componentPercentageVec;//饼图组成部分所占的百分比,由组成数量计算得来
QVector<QFont> m_componentLegendFontVec;//饼图图例的字体
QVector<QColor> m_componentLegendColorVec;//饼图图例的字体的颜色
QString m_titleName;//饼图标题名称
QFont m_titleFont;//饼图标题字体
QColor m_titleColor;//饼图标题字体颜色
};
#endif // HNPIECHART_H
2、实现文件如下:
#include "hnPieChart.h"
#include <QPainter>
#include <QFont>
#include <math.h>
hnPieChart::hnPieChart(QWidget *parent)
: QWidget(parent)
{
m_NumOfComponent = 0;
ui.setupUi(this);
}
hnPieChart::~hnPieChart()
{
}
void hnPieChart::ClearPieChart()
{
m_NumOfComponent = 0;
m_componentNameVec.clear();
m_componentNumberVec.clear();
m_componentColorVec.clear();
m_componentPercentageVec.clear();
m_componentLegendFontVec.clear();
m_componentLegendColorVec.clear();
}
void hnPieChart::SetChartTitle(const QString& titleName, QFont titleFont, QColor titleColor)
{
m_titleName = titleName;
m_titleFont = titleFont;
m_titleColor= titleColor;
}
void hnPieChart::AddComponentToChart(const QString& name, int Num, QColor color, QFont lengendFont, QColor legendColor)
{
m_componentNameVec.push_back(name);
m_componentNumberVec.push_back(Num);
m_componentColorVec.push_back(color);
m_componentLegendFontVec.push_back(lengendFont);
m_componentLegendColorVec.push_back(legendColor);
m_NumOfComponent++;
}
void hnPieChart::DrawPieChart()
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);//抗锯齿
QRect recTitle = ui.widget_title->geometry();
painter.setFont(m_titleFont);
painter.setPen(m_titleColor);
painter.drawText(recTitle, Qt::AlignCenter, m_titleName);//设置饼图标题
QRect recChart = ui.widget_chart->geometry();
int minSide = 0;
int bPx=0, bPy=0;
if (recChart.width() > recChart.height())
{
minSide = recChart.height();
bPx = recChart.x() + (recChart.width() - recChart.height()) / 2 + minSide / 10 / 2;
bPy = recChart.y() + minSide / 10 / 2;
}
else
{
minSide = recChart.width();
bPx = recChart.x() + minSide / 10 / 2;
bPy = recChart.y() + (recChart.height() - recChart.width()) / 2 + minSide / 10 / 2;
}
int PieDiameter = minSide * 9 / 10;
recChart = QRect(bPx, bPy, PieDiameter, PieDiameter);
QPoint PieCenter(bPx+PieDiameter/2,bPy+PieDiameter/2);
QBrush brush(Qt::SolidPattern);//设置画刷模式
int startAngle = 0;
int spanAngle = 0;
if (m_NumOfComponent==1)//饼图只有一个组成部分
{
painter.setPen(Qt::NoPen);
brush.setColor(m_componentColorVec[0]);
painter.setBrush(brush);
painter.drawPie(recChart, 0, 360*16);
painter.setFont(m_componentLegendFontVec[0]);
painter.setPen(m_componentLegendColorVec[0]);
int per = 100;
QString str = m_componentNameVec[0] + QString("(%1").arg(per) + "%)";
painter.drawText(recChart, Qt::AlignCenter, str);
}
else
{
for (int i = 0; i < m_NumOfComponent; i++)
{
spanAngle = 360 * m_componentPercentageVec[i] * 16;
painter.setPen(Qt::NoPen);
brush.setColor(m_componentColorVec[i]);
painter.setBrush(brush);
painter.drawPie(recChart, startAngle, spanAngle);
int middleAngle = startAngle + spanAngle / 2;
int middlePtx = PieCenter.rx() + PieDiameter / 2 * cos(middleAngle / 16.0 / 180 * 3.1416);
int middlePty = PieCenter.ry() - PieDiameter / 2 * sin(middleAngle / 16.0 / 180 * 3.1416);
int size = minSide / 10;
QRect recLegend;
painter.setPen(Qt::black);
if (middleAngle<90*16&&middleAngle>=0*16)//第一象限
{
painter.drawLine(middlePtx,middlePty,middlePtx + size/2,middlePty);
recLegend = QRect(middlePtx + size/2, middlePty - size/2, 2 * size, size);
}
if(middleAngle < 180*16&&middleAngle>=90*16)//第二象限
{
painter.drawLine(middlePtx, middlePty, middlePtx - size/2, middlePty);
recLegend = QRect(middlePtx - size/2 - 2 * size, middlePty - size/2, 2 * size, size);
}
if (middleAngle<270*16&&middleAngle>=180*16)//第三象限
{
painter.drawLine(middlePtx, middlePty, middlePtx - size/2, middlePty);
recLegend = QRect(middlePtx - size/2- 2 * size, middlePty - size/2, 2 * size, size);
}
if (middleAngle < 360*16&&middleAngle>=270*16)//第四象限
{
painter.drawLine(middlePtx, middlePty, middlePtx + size/2, middlePty);
recLegend = QRect(middlePtx + size/2, middlePty - size/2, 2 * size, size);
}
painter.setFont(m_componentLegendFontVec[i]);
painter.setPen(m_componentLegendColorVec[i]);
float per = m_componentPercentageVec[i] * 100;
QString str = m_componentNameVec[i] + QString("(%1").arg(per,0,'f', 2) + "%)";
painter.drawText(recLegend, Qt::AlignCenter, str);
startAngle += 360 * m_componentPercentageVec[i] * 16;
}
}
}
void hnPieChart::paintEvent(QPaintEvent *event)
{
DrawPieChart();
QWidget::paintEvent(event);
}
void hnPieChart::CalculatePercentage()
{
m_componentPercentageVec.resize(m_NumOfComponent);
int sum = 0;
for (int i = 0; i < m_NumOfComponent; i++)
{
sum += m_componentNumberVec[i];
}
for (int i = 0; i < m_NumOfComponent; i++)
{
double per = (double)m_componentNumberVec[i] / sum;
m_componentPercentageVec[i]=per;
}
}
3、ui文件如下:
4、调用如下:
#ifndef TEST_H
#define TEST_H
#include <QtWidgets/QMainWindow>
#include "ui_test.h"
#include "hnPieChart.h"
class test : public QMainWindow
{
Q_OBJECT
public:
test(QWidget *parent = 0);
~test();
private:
Ui::testClass ui;
hnPieChart m_PieChart;//声明对象
};
#endif // TEST_H
#include "test.h"
test::test(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//调用方式
m_PieChart.ClearPieChart();
m_PieChart.SetChartTitle(QString::fromLocal8Bit("超限状态图"), QFont(QString::fromLocal8Bit("微软雅黑"),12),Qt::black);
m_PieChart.AddComponentToChart(QString::fromLocal8Bit("正常"), 5352, Qt::cyan, QFont(QString::fromLocal8Bit("微软雅黑"), 10),Qt::black);
m_PieChart.AddComponentToChart(QString::fromLocal8Bit("拉出"), 20242, Qt::red, QFont(QString::fromLocal8Bit("微软雅黑"), 10),Qt::black);
m_PieChart.AddComponentToChart(QString::fromLocal8Bit("导高"), 5000, Qt::green, QFont(QString::fromLocal8Bit("微软雅黑"), 10), Qt::black);
m_PieChart.AddComponentToChart(QString::fromLocal8Bit("角度"), 21245, Qt::blue, QFont(QString::fromLocal8Bit("微软雅黑"), 10), Qt::black);
m_PieChart.AddComponentToChart(QString::fromLocal8Bit("磨耗"), 50000, Qt::magenta, QFont(QString::fromLocal8Bit("微软雅黑"), 10), Qt::black);
m_PieChart.CalculatePercentage();
ui.verticalLayout->addWidget(&m_PieChart);
}
test::~test()
{
}
5、运行效果如下: