废话少说,放码过来
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
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));