0、前言

主要是有任何改动时候就需要重新设计图片，不能适配不同控件大小，即使让它自由拉伸，但仪表盘放大缩小时候显示效果会变差。这篇文章设计了一个自己绘制的仪表盘，有背景表盘，刻度线、刻度值，指针，以及动态运行效果。

1、demo顶层设计

`代码调用，绑定滑动条信号到仪表盘的槽函数即可。`
```#include "widget.h"
#include "ui_frmwidget.h"
#include <QDebug>

Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);

connect(ui->horizontalSlider, &QSlider::valueChanged, ui->dial, &MyDial::valueChanged);
}

Widget::~Widget()
{
delete ui;
}```

## 2、绘制仪表盘

```void MyDial::drawBg(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(QColor(, , ));
painter->drawEllipse(-r, -r, r * , r * );

painter->setBrush(QColor(, , ));
painter->setPen(Qt::NoPen);
painter->drawEllipse(-r, -r, r * , r * );
painter->restore();
}```

```void MyDial::drawDial(QPainter *painter)
{
double lineWidth = ;
painter->save();

painter->rotate(Angle);
/*
为什么旋转？
如果不旋转画笔的坐标轴，那么每次画的时候需要按照角度来重新计算，x=r*cos,y=r*sin. 计算复杂
但是如果旋转坐标轴，那么首次旋转angle角度，则y轴和第一条斜线重合，x=0，只需要计算y。
画100条线，就是分100份来表示进度。每次旋转的角度=360-(起始角度*2--分左右)/100
*/
double rotate = (double)( - (Angle * )) / ;

for (int i = ; i <= ; i++) {
QColor color = QColor(, , );
if(i>) color = QColor(, , );
if((i % ) == )
{
painter->setPen(QPen(color, 1.3*lineWidth));
painter->drawLine(, r, , r / 1.2);
}
else if((i % ) == )
{
painter->setPen(QPen(color, *lineWidth));
painter->drawLine(, r, , r / 1.1);
}
painter->rotate(rotate);
}

painter->restore();
}```

```void MyDial::drawScaleNum(QPainter *painter)
{
painter->save();

qDebug()<< "drawText";

painter->setFont(QFont("Arial", ));
painter->setPen(QPen(QColor(,,)));
QFontMetricsF fm = QFontMetricsF(painter->font());

int gap = (-Angle*) / ;
for(int i=; i<=; i+=)
{
int angle = +Angle+gap*i;  //角度,10格子画一个刻度值

float angleArc =( angle % ) * 3.14 / ; //转换为弧度
int x = (r)*cos(angleArc);
int y = (r)*sin(angleArc);

QString speed = QString::number(i);
int w = (int)fm.width(speed);
int h = (int)fm.height();
x = x - w/;
y = y + h/;

qDebug()<< "x:"<<x<<" y:"<<y;
//painter->drawPoint(QPointF(x, y));
painter->drawText(QPointF(x, y),speed);
}
painter->restore();
}```

```void MyDial::drawIndicator(QPainter *painter)
{
painter->save();
QPolygon pts;
pts.setPoints(, -, , , , , r);
double degRotate =Angle +  (360.0 - Angle - Angle) /  * percent;

//画指针
painter->rotate(degRotate);
painter->setPen(QColor(, , )); // 边框颜色
painter->drawConvexPolygon(pts);
painter->restore();

// 画中心圆圈
painter->setPen(Qt::NoPen);  //填满没有边界
painter->drawEllipse(-, -, , );

painter->restore();
}```

```void MyDial::drawText(QPainter *painter)
{
painter->save();

painter->setFont(QFont("Arial", ));
painter->setPen(QPen(QColor(,,)));
QFontMetricsF fm = QFontMetricsF(painter->font());
QString speed = QString::number(percent) + " km/h";
int w = (int)fm.width(speed);
int h = (int)fm.height();
painter->restore();
}```

```void MyDial::valueChanged(int value)
{
this->percent = value;
update();
}```

```void MyDial::paintEvent(QPaintEvent *)
{
int width = this->width();
int height = this->height();

//绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width / , height / );

int side = qMin(width, height);
painter.scale(side / 200.0, side / 200.0);

//绘制最外框圆形背景
drawBg(&painter);
//绘制刻度
drawDial(&painter);
//绘制范围值及当前值文字
drawScaleNum(&painter);
//绘制指针
drawIndicator(&painter);
//绘制表盘上文本当前值
drawText(&painter);
}```

## 4、参考文档

1、Qt编写自定义控件1-汽车仪表盘

https://www.cnblogs.com/feiyangqingyun/p/10739099.html

2、Qt总结之八：绘制仪表盘

https://blog.csdn.net/Aidam_Bo/article/details/85266798

3、Qt自定义控件 -- 仪表盘01

https://blog.csdn.net/pingis58/article/details/82150237

Qt自定义控件之仪表盘2--QPaint绘制仪表盘

https://www.cnblogs.com/pingwen/p/13416933.html

## Qt自定义控件之仪表盘2--QPaint绘制仪表盘的更多相关文章

1. Qt自定义控件大全（一）云台仪表盘控件

做过安防视频监控的同学都清楚,在视频监控系统软件上都可以看到一个云台控制区域,可以对球机进行下下左右等八个方位的运动控制,还可以进行复位,一般都是美工作图好,然后贴图的形式加入到软件中,好处是程序简单 ...

2. C# GDI绘制仪表盘（纯代码实现）

纯代码实现GDI绘制仪表盘,效果在代码下面. public partial class HalfDashboardUc : UserControl { /// <summary> /// ...

本系列主要使用Qt painter来实现一些基础控件.主要是对平时自行编写的一些自定义控件的总结. 为了简洁.低耦合,我们尽量不使用图片,qrc,ui等文件,而只使用c++的.h和.cpp文件. 由于 ...

4. Qt自定义控件系列(一) --- 圆形进度条

本系列主要使用Qt painter来实现一些基础控件.主要是对平时自行编写的一些自定义控件的总结. 为了简洁.低耦合,我们尽量不使用图片,qrc,ui等文件,而只使用c++的.h和.cpp文件. 由于 ...

5. paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制

源地址:http://blog.csdn.net/attilax/article/details/12343625 paip.提升用户体验---c++ qt自定义窗体(1)---标题栏的绘制 效果图: ...

6. 编写Qt Designer自定义控件（一）——如何创建并使用Qt自定义控件

在使用Qt Designer设计窗体界面时,我们可以使用Widget Box里的窗体控件非常方便的绘制界面,比如拖进去一个按钮,一个文本编辑器等.虽然Qt Designer里的控件可以满足我们大部分的 ...

7. Qt自定义控件(插件)并添加到QtDesigher

之前使用Qt的时候都是手写代码的(因为批量按钮可以使用数组实现),但当界面越来越复杂时,这种开发效率就太低了; 后来就开始使用QtDesigner,但要使QtDesigner支持我自己写的控件,需要提 ...

8. 【Qt for Android】OpenGL ES 绘制彩色立方体

Qt 内置对OpenGL ES的支持.选用Qt进行OpenGL ES的开发是很方便的,很多辅助类都已经具备.从Qt 5.0開始添加了一个QWindow类,该类既能够使用OpenGL绘制3D图形,也能够 ...

9. QT自定义控件插件化简要概述

1.选择 "其他项目"->"Qt4 设计师自定义控件" **最好选中所有的编译器平台,由于目前使用的Qt Creator是MSVC2015 32位,因此要 ...

10. Qt自定义控件

Qt创建自定义控件教程 一.新建Qt设计师控件 二.设置项目名称 三.选择kits 这里取消Debug选项,不需要这个选项都是编译为dll文件直接调用. 删除掉MyControl原有的.h和cpp文件 ...

## 随机推荐

1. 关于安装Apache之后，解析PHP的配置

2. JAVA的垃圾回收机制

1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的 ...

3. CSS 透明度 设置 兼容IE FF

filter:Alpha(Opacity=80);/*IE*/ -moz-opacity:0.8;/*FF*/ opacity: 0.8;/*所有元素*/ 参数设置说明: Alpha(Opacity= ...

4. Theano深度学习结构分析

Reference:Theano入门三部曲 http://deeplearning.net/tutorial/logreg.html  (Softmax回归) http://deeplearning. ...

5. 千万不要在JS中使用连等赋值操作

前言 文章标题这句话原本是在国外某JavaScript规范里看到的,当时并没有引起足够的重视,直到最近一次出现了bug发现JS里的连等赋值操作的特色(坑). 网上搜索一番发现一个非常好的连等赋值的(来 ...

6. 基于Struts2框架实现登录案例

一,准备工作  1)新建web项目,并导入Struts2jar文件和配置web.xml文件. struts2 jar文件 web.xml文件 <?xml version="1.0&qu ...

7. oracle db shutdown immediate&ndash;multi Instance

[oracle@redhat4 ~]\$ sqlplus / as sysdba@orcl SQL*Plus: Release 11.2.0.1.0 Production on Tue Oct 6 21 ...

8. 论山寨手机与Android 【11】移动网络规范的合纵连横

上一章我们讨论了SmartPhone BP部分的硬件系统,接下去我们将讨论SmartPhone BP部分的软件系统.所谓BP,指的是基带处理器(Baseband Processor),又称为通讯处理器 ...

9. 重温Javascript（四）-函数

函数 函数声明提升,在执行代码之前会先读取函数声明 sayHi(); function sayHi(){ alert("Hi!"); } 递归 arguments.callee是指 ...

10. SecureCRT永久设置保护眼睛配色方案

配色后效果如下: 下面开始配色 1.选项(Options)==>会话选项(Sessions options)==>终端(Terminal)==>仿真(Emulation) 按图中标注 ...