废话少说,放码过来
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();protected:void paintEvent(QPaintEvent *event);private:Ui::Widget *ui;QTimer *timer;int currentValue; //实现指针移动int mark = 0; // 控制指针的移动方向
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"#include <QPainter>
#include <QTimer>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);timer = new QTimer(this);currentValue = 0;connect(timer,&QTimer::timeout,[=](){if(mark == 0){currentValue++;if(currentValue >= 60)mark = 1;}else if(mark ==1){currentValue--;if(currentValue <= 0)mark = 0;}update(); // 触发绘图事件});timer->start(30);}Widget::~Widget()
{delete ui;
}void Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);//设置抗锯齿painter.setRenderHints(QPainter::Antialiasing,true);//设置黑色的背景色painter.setBrush(Qt::black); // 设置 黑色的画刷painter.drawRect(rect());//坐标系,平移到中心painter.translate(rect().center());//设置渐变色
// QRadialGradient radialGradient(0,0,height()/2);//渐变圆心,渐变半径
// radialGradient.setColorAt(0.1,QColor(255,0,0,80));
// radialGradient.setColorAt(1,QColor(255,0,0,250));
// // 使用这个渐变色创建画刷
// painter.setBrush(QBrush(radialGradient));
// //画出渐变的(椭)圆 -- 大圆
// painter.setBrush(Qt::NoBrush); // 丢弃渐变画刷painter.drawEllipse(QPoint(0,0),height()/2,height()/2);//画小圆painter.setPen(QPen(Qt::white,3)); //设置白色的画笔painter.drawEllipse(QPoint(0,0),60,60);//显示当前值:painter.setFont(QFont("华文宋体",20));painter.drawText(QRect(-60,-60,120,120),Qt::AlignCenter,QString::number(currentValue));//保存原点:painter.save(); // 三点钟方向//画刻度://1.算出一个刻度需要的角度 270 度分成 50份double angle = 240*1.0/60; //需要先转为double类型,否则销售几乎部分会被吞掉造成误差//2.设置起始角度painter.rotate(150); // 从135度开始//设置字体样式:painter.setFont(QFont("华文宋体",13));//3.分类讨论 画出所有刻度for(int i=0;i<=60;++i){//包括0- 一共有51跟刻度线if(i%5 == 0){ // 被5 整除进一步细分表盘//画出长刻度上的数字标度if(150+angle*i < 240){ // 表盘左边数据翻转显示painter.rotate(180);painter.drawText(-(height()/2-20-10),8,QString::number(i*4));painter.rotate(-180);}else{//右边数据正常显示painter.drawText(height()/2-20-45,8,QString::number(i*4));}//画出一个长刻度painter.drawLine(height()/2-20,0,height()/2-3,0);}else{//画出一个长刻度painter.drawLine(height()/2-10,0,height()/2-3,0);}painter.rotate(angle);//选择angle的角度准备去画下一个刻度}//画指针 --> 线//先恢复到之前保存的原点:painter.restore();painter.save(); // 接着保存原点// 通过定时器去改变currentValue的值,去控制指针的移动painter.rotate(150+angle*currentValue); // 进行坐标系偏移painter.drawLine(60,0,height()/2-20-38,0); // 58//画扇形painter.restore();QRect rentangle(-height()/2,-height()/2,height(),height());painter.setPen(Qt::NoPen);painter.setBrush(QColor(255,128,64,150));painter.drawPie(rentangle,(-150)*16,-angle*currentValue*16);}
效果演示
详细说明
画图准备- 背景
QPainter painter(this);//设置抗锯齿painter.setRenderHints(QPainter::Antialiasing,true);//设置黑色的背景色painter.setBrush(Qt::black); // 设置 黑色的画刷painter.drawRect(rect());
坐标系平移
平移原点
//坐标系,平移到中心painter.translate(rect().center());
平移坐标系弧度
//2.设置起始角度painter.rotate(150); // 从135度开始
画大圆(渐变色)
//设置渐变色
// QRadialGradient radialGradient(0,0,height()/2);//渐变圆心,渐变半径
// radialGradient.setColorAt(0.1,QColor(255,0,0,80));
// radialGradient.setColorAt(1,QColor(255,0,0,250));
// // 使用这个渐变色创建画刷
// painter.setBrush(QBrush(radialGradient));
// //画出渐变的(椭)圆 -- 大圆
// painter.setBrush(Qt::NoBrush); // 丢弃渐变画刷painter.drawEllipse(QPoint(0,0),height()/2,height()/2);
画小圆
//画小圆painter.setPen(QPen(Qt::white,3)); //设置白色的画笔painter.drawEllipse(QPoint(0,0),60,60);
原点保存和恢复
painter.save(); //保存原点: 三点钟方向/* 中间经历了某种平移
painter.rotate(150); // 从135度开始*/
painter.restore(); //恢复到之前保存的位置
画刻度
//1.算出一个刻度需要的角度 270 度分成 50份double angle = 240*1.0/60; //需要先转为double类型,否则销售几乎部分会被吞掉造成误差//2.设置起始角度painter.rotate(150); // 从135度开始//设置字体样式:painter.setFont(QFont("华文宋体",13));//3.分类讨论 画出所有刻度for(int i=0;i<=60;++i){//包括0- 一共有61根刻度线if(i%5 == 0){ // 被5 整除进一步细分表盘//画出长刻度上的数字标度if(150+angle*i < 240){ // 表盘左边数据翻转显示painter.rotate(180);painter.drawText(-(height()/2-20-10),8,QString::number(i*4));painter.rotate(-180);}else{//右边数据正常显示painter.drawText(height()/2-20-45,8,QString::number(i*4));}//画出一个长刻度painter.drawLine(height()/2-20,0,height()/2-3,0);}else{//画出一个长刻度painter.drawLine(height()/2-10,0,height()/2-3,0);}painter.rotate(angle);//选择angle的角度准备去画下一个刻度}
画扇形
//画扇形painter.restore();QRect rentangle(-height()/2,-height()/2,height(),height());painter.setPen(Qt::NoPen);painter.setBrush(QColor(255,128,64,150));painter.drawPie(rentangle,(-150)*16,-angle*currentValue*16);
定时器实现指针/扇形移动
构造函数里初始化定时器
timer = new QTimer(this);currentValue = 0;connect(timer,&QTimer::timeout,[=](){if(mark == 0){currentValue++;if(currentValue >= 60)mark = 1;}else if(mark ==1){currentValue--;if(currentValue <= 0)mark = 0;}update(); // 触发绘图事件});timer->start(30);
扇形移动
// 通过定时器去改变currentValue的值,去控制指针的移动painter.rotate(150+angle*currentValue); // 进行坐标系偏移painter.drawLine(60,0,height()/2-20-38,0); // 58//画扇形painter.restore();QRect rentangle(-height()/2,-height()/2,height(),height());painter.setPen(Qt::NoPen);painter.setBrush(QColor(255,128,64,150));painter.drawPie(rentangle,(-150)*16,-angle*currentValue*16);
表盘中间显示 "速度"字样
//显示当前值:painter.setFont(QFont("华文宋体",20));painter.drawText(QRect(-60,-60,120,120),Qt::AlignCenter,QString::number(currentValue));