mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPainter>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
// 绘制圆环
void DrawCircle_line(QPainter& painter,int radius, int width);
protected:
void paintEvent(QPaintEvent*);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
//最外细圆线
void MainWindow::DrawCircle_line(QPainter& painter,int radius, int width)
{
//保存绘图对象
painter.save();
//计算大小圆路径
// PainterPath 是一个用于存储图形(如线条、曲线、椭圆、多边形等)的类
QPainterPath outRing;
QPainterPath inRing;
// moveTo() 函数将当前点移动到坐标 (0, 0) 位置,此时路径上只有一个起始点,还没有定义任何线条或曲线。
// 其实这段代码可以省略,因为创建 QPainterPath 对象时,它的默认起点坐标是 (0, 0)。
// 因此,在 addEllipse() 和 arcTo() 函数中不需要移动路径的起始点。
// 但是,如果 QPainterPath 对象已经存在其他路径,且这些路径的最后一点不是起点 (0, 0),那么这段代码就很重要了。
outRing.moveTo(0,0);
inRing.moveTo(0,0);
// arcTo() 函数的前两个参数表示圆弧的外接矩形的左上角的坐标
// 2 * radius 和 2 * radius 表示矩形的宽度和高度,即圆弧的直径。
// 最后两个参数 -30 和 240 表示绘制圆弧的起始角度和旋转的角度范围。
outRing.arcTo(-radius, -radius, 2*radius, 2*radius,-30, 240);
// addEllipse() 函数来添加一个圆形路径,用于绘制内圆环
// 第一个参数 -radius+ width 和第二个参数 -radius+ width 分别表示内圆环的圆心的坐标,
// 即在外圆环的基础上向右移动 width 像素和向下移动 width 像素
// 第三个参数 2*(radius-width) 和第四个参数 2*(radius-width) 分别表示内圆环的直径。
inRing.addEllipse(-radius + width, -radius + width, 2*(radius - width), 2 * (radius - width));
// 调用 outRing 的 closeSubpath() 函数来将路径封闭起来
// closeSubpath() 函数的作用是将当前路径的起始点和最后一个点之间连接起来,形成一个封闭的路径。
// 这样做的好处是在绘制这个路径时可以填充颜色等操作,并且当路径有交叉部分时也可以正确地绘制出来。
outRing.closeSubpath();
//设置画刷
painter.setBrush(QColor(5,228,255));
//大圆减小圆
// subtract() 函数用于返回一个从 QPainterPath 对象中减去其他 QPainterPath 对象的新对象。
// 这里我们使用 subtracted() 函数来获取两个圆环路径的差集,从而绘制出一个环形。
painter.drawPath(outRing.subtracted(inRing));
painter.restore();
}
void MainWindow::paintEvent(QPaintEvent*)
{
QPainter painter(this);
int width=this->width();
int height=this->height();
int radius=((width>height)?height:width)/2.0;//仪表盘的中心位置
//移动画笔到中心位置
painter.translate(this->width() / 2, this->height() / 2);
//启用反锯齿
painter.setRenderHint(QPainter::Antialiasing, true);
painter.setPen(Qt::NoPen);
DrawCircle_line(painter, radius, 10);
}