1.头文件
#pragma once
#include <QtGui/qpainter.h>
#include <QtWidgets/qwidget.h>
#include <QtCore/qtimer.h>
class Painter : public QWidget
{
//Q_OBJECT
public:
Painter(QWidget *parent = nullptr);
void startTimer(int interval);
void stopTimer();
/* 用于启动动态饼图 */
void setAngle(double percent);
void setLabel(int _width, int _height);
protected:
void paintEvent(QPaintEvent *event) override;
private slots:
void updateAngle();
private:
/* 绘制饼图 */
void drawPie();
/* 绘制环形 */
void drawArc();
int angle;
QTimer * timer;
int label_width;
int label_height;
};
2.源文件
#include "painter.h"
//todo 在创建子类对象时,为了初始化从父类继承来的数据成员,系统需要先调用其父类的构造方法。
Painter::Painter(QWidget * parent) : QWidget(parent), angle(0), timer(new QTimer(this))//todo 显式调用父类有参构造,父类QWidget只声明了带参构造函数,子类构造必须显式调用父类有参构造
{
//qw = parent;
//timer = new QTimer(this);
connect(timer,&QTimer::timeout,this,&Painter::updateAngle);
label_width = parent->width();
label_height = parent->height();
resize(label_width, label_height);
startTimer(500);
}
void Painter::startTimer(int interval)
{
timer->start(interval);
}
void Painter::stopTimer()
{
timer->stop();
}
void Painter::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
/* 绘制饼图 */
drawPie();
/* 绘制环形 */
//drawArc();
}
void Painter::drawPie()
{
if (angle <= 360)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿,使图形更平滑
// 计算窗口的最小边长,确保饼状图是正方形的
//int side = qMin(width(), height());
// 设置视口,使饼状图居中显示(设备坐标系: 也是物理坐标系。即真实的的物理坐标系(单位为像素),拉大窗口中,看上去图会小)
//painter.setViewport(231, 30, 20, 20);
//painter.setViewport((width() - side) / 2, (height() - side) / 2, side, side);
//painter.setViewport(0, 10, 20, 20);
int side = qMin(label_width, label_height);
painter.setViewport((label_width - side) / 2, (label_height - side) / 2 + 10, side, side);
//painter.setViewport(0, 10, label_width, label_height);
painter.setWindow(-50, -50, 100, 100);
// 绘制第一个扇形
painter.setPen(Qt::NoPen);// 设置无边框
// 创建锥形渐变(QConicalGradient)
QConicalGradient conicalGradient(0, 0, 0); // 中心点(50,50),起始角度为0
conicalGradient.setColorAt(1.0, QColor(0, 255, 0));
conicalGradient.setColorAt(0.75, QColor(0, 255, 0));
conicalGradient.setColorAt(0.5, QColor("yellow"));
conicalGradient.setColorAt(0.25, QColor("yellow"));
conicalGradient.setColorAt(0.0, QColor(255, 0, 0));
// conicalGradient.setColorAt(0/6, QColor("red"));
// conicalGradient.setColorAt(1/6, QColor("yellow"));
// conicalGradient.setColorAt(2/6, QColor("lime"));
// conicalGradient.setColorAt(3/6, QColor("aqua"));
// conicalGradient.setColorAt(4/6, QColor("blue"));
// conicalGradient.setColorAt(5/6, QColor("magenta"));
// conicalGradient.setColorAt(1, QColor("red"));
// 线性渐变
//QLinearGradient linearGradient(0, 0, 100, 100); // 从(0,0)到(100,100)的线性渐变
//linearGradient.setColorAt(0.0, Qt::green);
//linearGradient.setColorAt(0.5, Qt::yellow);
//linearGradient.setColorAt(1.0, Qt::red);
//painter.setBrush(linearGradient);
// 径向渐变
//QRadialGradient radialGradient(50,50, 50); // 中心点(50,50),半径50
//radialGradient.setColorAt(0, QColor("red"));
//radialGradient.setColorAt(0.5, QColor("yellow"));
//radialGradient.setColorAt(1, QColor("purple"));
//radialGradient.setColorAt(0.8, Qt::blue);
// 设置渐变画刷
//painter.setBrush(conicalGradient);
painter.setBrush(Qt::blue);
//painter.setBrush(QColor(255, 0, 0));// 设置填充颜色为红色
// 绘制扇形,参数分别为:矩形左上角坐标、宽度、高度(这个大小是按照窗口的比例算的),起始角度、跨度角度(这两个角度必须为16的倍数)
painter.drawPie(-50, -50, 100, 100, -0 * 16, -angle * 16);
//painter.drawPie(-40, -40, 80, 80, -0 * 16, -angle * 16);
//painter.drawRect(-50, -50, 100, 100);
// 绘制第二个扇形
painter.setBrush(Qt::gray); // 设置填充颜色为灰色
// 绘制扇形,剩余部分为灰色
//painter.drawPie(-40, -40, 80, 80, -angle * 16, -(360 - angle) * 16);
painter.drawPie(-50, -50, 100, 100, -angle * 16, -(360 - angle) * 16);
}
else
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿,使图形更平滑
// 计算窗口的最小边长,确保饼状图是正方形的
//int side = qMin(width(), height());
int side = qMin(label_width, label_height);
painter.setViewport((label_width - side) / 2, (label_height - side) / 2 + 10, side, side);
//painter.setViewport(0, 10, label_width, label_height);
painter.setWindow(-50, -50, 100, 100);
// 绘制第一个扇形
painter.setPen(Qt::NoPen);// 设置无边框
painter.setBrush(Qt::blue);
//painter.drawPie(-40, -40, 80, 80, -0 * 16, -360 * 16);
painter.drawPie(-50, -50, 100, 100, -0 * 16, -360 * 16);
//painter.drawRect(-50, -50, 100, 100);
}
}
void Painter::drawArc()
{
if (angle <= 360)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿,使图形更平滑
// 计算窗口的最小边长,确保饼状图是正方形的
//int side = qMin(width(), height());
int side = qMin(label_width, label_height);
//painter.setViewport((label_width - side) / 2, (label_height - side) / 2 + 20, side, side);
painter.setViewport((label_width - side) / 2, (label_height - side) / 2, side, side);
//painter.setViewport(0, 10, label_width, label_height);
painter.setWindow(-50, -50, 100, 100);
//painter.setWindow(-100, -100, 200, 200);
//painter.setWindow(-80, -80, 160, 160);
QPen pen;
pen.setWidth(10);
/*设置圆弧连接处为圆形*/
pen.setJoinStyle(Qt::RoundJoin);
pen.setCapStyle(Qt::RoundCap);
pen.setBrush(Qt::gray);
painter.setPen(pen);
//painter.drawArc(-50, -50, 100, 100, 0, 360 * 16);
painter.drawArc(-30, -30, 60, 60, 0, 360 * 16);
pen.setWidth(8);
/*设置圆弧连接处为圆形*/
pen.setJoinStyle(Qt::RoundJoin);
pen.setCapStyle(Qt::RoundCap);
int percent = angle / 3.6;
if (percent <= 50)
{
//pen.setColor(Qt::green);
pen.setBrush(Qt::green);
}
else if (percent > 50 && percent <= 75)
{
pen.setColor(Qt::yellow);
}
else
{
pen.setColor(Qt::red);
}
// 线性渐变
//QLinearGradient linearGradient(50, 50, -50, -50); // 从(100,100)到(-100,-100)的线性渐变
//linearGradient.setColorAt(0.0, QColor("#ffffff"));
//linearGradient.setColorAt(1.0, QColor("#33FF00"));
//pen.setBrush(linearGradient);
painter.setPen(pen);
painter.drawRect(-50, -50, 100, 100);
//painter.drawArc(-50, -50, 100, 100, -0 * 16, -angle * 16);
painter.drawArc(-30, -30, 60, 60, -0 * 16, -angle * 16);
//painter.drawArc(-100, -100, 100, 100, -0 * 16, -angle * 16); //(这两个角度必须为16的倍数)
//painter.drawArc(-40, -40, 80, 80, 0 * 16, angle * 16);
}
else
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿,使图形更平滑
// 计算窗口的最小边长,确保饼状图是正方形的
//int side = qMin(width(), height());
//painter.setViewport(0, 10, label_width, label_height);
int side = qMin(label_width, label_height);
//painter.setViewport((label_width - side) / 2, (label_height - side) / 2 + 20, side, side);
painter.setViewport((label_width - side) / 2, (label_height - side) / 2, side, side);
//painter.setViewport(0, 10, label_width, label_height);
painter.setWindow(-50, -50, 100, 100);
//painter.setWindow(-80, -80, 160, 160);
QPen pen;
pen.setWidth(12);
/*设置圆弧连接处为圆形*/
pen.setJoinStyle(Qt::RoundJoin);
pen.setCapStyle(Qt::RoundCap);
pen.setBrush(Qt::gray);
painter.setPen(pen);
//painter.drawArc(-50, -50, 100, 100, 0, 360 * 16);
painter.drawArc(-30, -30, 60, 60, 0, 360 * 16);
pen.setWidth(10);
/*设置圆弧连接处为圆形*/
pen.setJoinStyle(Qt::RoundJoin);
pen.setCapStyle(Qt::RoundCap);
int percent = angle / 3.6;
if (percent <= 25)
{
//pen.setColor(Qt::green);
pen.setBrush(Qt::green);
}
else if (percent > 25 && percent <= 75)
{
pen.setColor(Qt::yellow);
}
else
{
pen.setColor(Qt::red);
}
// 线性渐变
//QLinearGradient linearGradient(50, 50, -50, -50); // 从(100,100)到(-100,-100)的线性渐变
//linearGradient.setColorAt(0.0, QColor("#ffffff"));
//linearGradient.setColorAt(1.0, QColor("#33FF00"));
//pen.setBrush(linearGradient);
painter.setPen(pen);
painter.drawRect(-50, -50, 100, 100);
//painter.drawArc(-50, -50, 100, 100, -0 * 16, -angle * 16);
painter.drawArc(-30, -30, 60, 60, -0 * 16, -angle * 16);
//painter.drawRect(-50, -50, 100, 100);
}
}
void Painter::updateAngle()
{
angle += 10;// 每次更新角度增加10度
//if (angle > 360)
// angle = 0;// 如果角度超过360度,重置为0度
//update();// 调用update()函数,触发重绘事件
//if (angle < 360)
{
update();
}
}
/* 用于启动动态饼图 */
void Painter::setAngle(double percent)
{
angle = percent * 360;
}
void Painter::setLabel(int _width, int _height)
{
label_width = _width;
label_height = _height;
}