基于Qt的速度仪表盘控件实现

本文将详细讲解一个基于Qt的速度仪表盘控件的实现过程,并对代码进行详细的注释说明。该控件可以模拟汽车仪表盘的外观,并通过滑动条动态改变速度显示。本文将从代码结构、绘制组件到实现细节进行讲解,帮助您理解如何使用Qt框架自定义绘制控件。

在这里插入图片描述

1. 仪表盘控件构造函数

Dashboard类的构造函数中,设置了控件的背景颜色为黑色:

Dashboard::Dashboard(QWidget *parent) : QWidget(parent)
{// 设置背景色为黑色QPalette bgpal = palette();bgpal.setColor(QPalette::Background, QColor(0, 0, 0));setPalette(bgpal);
}

在这里,我们通过QPalette对象设置控件的背景色为黑色。如果需要其他背景颜色,只需修改QColor(0,0,0)即可。


2. 设置最大刻度

函数setScale允许我们设置速度表盘的最大值(例如120KM/h):

void Dashboard::setScale(const qreal max)
{// 设置最大刻度值MaxScale = max;// 更新控件显示update();
}

MaxScale保存了仪表盘的最大刻度值,调用update()触发控件重绘,从而更新显示。


3. paintEvent 绘制事件

paintEvent是绘制控件的核心函数,负责绘制仪表盘的所有元素:

void Dashboard::paintEvent(QPaintEvent*)
{// 创建QPainter对象QPainter painter(this);int width = this->width();int height = this->height();// 计算半径,使得仪表盘始终适应窗口尺寸int radius = ((width > height) ? height : width) / 2;// 移动画笔中心到控件的中下部painter.translate(width / 2, height * 0.6);// 启用抗锯齿,提高绘图质量painter.setRenderHint(QPainter::Antialiasing, true);// 设置无笔绘制,只填充颜色painter.setPen(Qt::NoPen);// 设置画刷颜色为紫色painter.setBrush(QColor(138, 43, 226));// 调用各个绘制函数,绘制仪表盘不同部分DrawDigital(painter, radius - 10); // 绘制刻度数字DrawCircle(painter, radius - 35);  // 绘制外圆DrawSmallScale(painter, radius - 60); // 绘制小刻度DrawText(painter, radius / 5); // 绘制中心文字DrawPointer(painter, radius - 100); // 绘制指针
}

该函数首先通过QPainter对象进行绘图,确定控件的宽高,并计算适应当前窗口的半径。translate函数将画笔的原点移动到控件的中下部,使得仪表盘绘制的中心位于该位置。启用了抗锯齿(Antialiasing)以确保绘制质量较高。

接下来,调用了多个辅助函数来绘制仪表盘的不同部分,包括刻度、外圆、指针等。


4. 绘制组件函数

下面是各个辅助函数的讲解,每个函数负责绘制仪表盘的一部分。

4.1 绘制刻度数字 (DrawDigital)

该函数负责在仪表盘的外圈上绘制数字刻度:

void Dashboard::DrawDigital(QPainter& painter, int radius)
{// 设置画笔颜色为用户自定义颜色painter.setPen(m_color);QFont font;font.setFamily("Cambria");font.setPointSize(12);painter.setFont(font);// 依次绘制0, 10, 20...等刻度数字for (int i = 0; i < 13; ++i) {QPointF point(0, 0);painter.save();// 计算数字的位置point.setX(radius * qCos(((210 - i * 20) * M_PI) / 180));point.setY(radius * qSin(((210 - i * 20) * M_PI) / 180));painter.translate(point.x(), -point.y());// 旋转文字,使其朝向正确painter.rotate(-120 + i * 20);// 在计算的位置绘制数字painter.drawText(-15, 0, 30, 20, Qt::AlignCenter, QString::number(i * (MaxScale) / 12));painter.restore();}// 还原画笔状态painter.setPen(Qt::NoPen);
}

此函数使用正弦和余弦函数来计算每个数字的绘制位置,并通过旋转(rotate)保证数字的正确方向。

4.2 绘制外圆 (DrawCircle)

绘制仪表盘的外圈,包括渐变色效果:

void Dashboard::DrawCircle(QPainter& painter, int radius)
{painter.save();// 定义外圈和内圈路径QPainterPath outRing, inRing;outRing.moveTo(0, 0);inRing.moveTo(0, 0);// 绘制外圈弧形outRing.arcTo(-radius, -radius, 2 * radius, 2 * radius, -31, 242);inRing.addEllipse(-radius + 20, -radius + 20, 2 * (radius - 20), 2 * (radius - 20));outRing.closeSubpath();// 设置渐变色效果QRadialGradient radialGradient(0, 0, radius, 0, 0);radialGradient.setColorAt(0.93, m_color);  // 外部为自定义颜色radialGradient.setColorAt(1, QColor(0, 0, 0));  // 内部为黑色// 使用渐变色进行填充painter.setBrush(radialGradient);painter.drawPath(outRing.subtracted(inRing));painter.restore();
}

该函数绘制了一个带有渐变色效果的外圈。arcTo用于绘制弧形外圈,addEllipse用于绘制内圈,渐变色效果通过QRadialGradient实现。

4.3 绘制指针 (DrawPointer)

指针的绘制逻辑如下:

void Dashboard::DrawPointer(QPainter& painter, int radius)
{QPainterPath pointPath;// 定义指针的路径(形状)pointPath.moveTo(10, 0);pointPath.lineTo(1, -radius - 25);  // 指针的长度pointPath.lineTo(-1, -radius - 25);pointPath.lineTo(-10, 0);pointPath.arcTo(-10, 0, 20, 20, 180, 180);painter.save();// 设置渐变颜色QRadialGradient radialGradient(0, 0, radius, 0, 0);radialGradient.setColorAt(0, QColor(0, 199, 140, 150));radialGradient.setColorAt(1, QColor(255, 153, 18, 150));// 根据当前速度旋转指针painter.rotate(240 / (MaxScale) * degRotate - 120);painter.setBrush(radialGradient);// 绘制指针painter.drawPath(pointPath);painter.restore();
}

该函数绘制了速度表的指针。QPainterPath用于定义指针的形状,rotate函数根据当前速度值旋转指针,使其指向正确的位置。


5. 使用滑动条控制速度显示

MainWindow类中,通过滑动条来动态改变速度表的值:

void MainWindow::on_horizontalSlider_sliderMoved(int position)
{ui->widget->valueChanged(position);
}

当滑动条被移动时,position参数表示当前滑块的位置,并通过调用valueChanged函数将其传递给仪表盘控件,进而更新指针的显示位置。


总结

通过本文的讲解,您已经了解了如何使用Qt绘制自定义的速度仪表盘控件。该控件通过QPainter对象和一些数学计算来绘制表盘的刻度、外圈和指针,并且可以通过滑动条动态改变显示的速度值。

为了进一步改进,您可以添加更多功能,比如让指针的移动更平滑、增加不同颜色的主题、设置更多自定义选项等。希望本文能够为您的Qt开发提供帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1556528.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ事务模块

目录 消息分发​​​​​​​ 负载均衡 幂等性保障 顺序性保障 顺序性保障方案 二号策略:分区消费 三号策略:消息确认机制 四号策略: 消息积压 RabbitMQ集群 选举过程 RabbitMQ是基于AMQP协议实现的,该协议实现了事务机制&#xff0c;要么全部成功&#xff0c;要么全…

2025,企业管理平台的理想模型V0.1

1.前言 近期出于综合考虑&#xff0c;准备休息一段时间......... 在这段时间里&#xff0c;准备重新梳理下企业管理平台应该具备的能力.并准备使用开源项目来一次组合式组装&#xff0c;最终形成一个初步可行的运行平台。 2.企业管理平台的主要组成 企业管理平台不是独立存…

安卓如何实现双击触摸唤醒点亮屏幕功能-Android framework实战开发

背景 经常有学员朋友在群里问到一个目前市场上常见的功能&#xff1a; 手机待机时候双击屏幕可以唤醒点亮手机屏幕功能 如何实现这个功能&#xff0c;经常有同学在群里求助&#xff0c;今天就刚好来讨论一下这个待机时候双击触摸唤醒点亮屏幕的功能的实现方案。 功能核心方案设…

深入理解 Spring Cache 的工作原理及集成其它第三方缓存

目录 1、Spring Cache 简介2、常用注解2.1、常用注解介绍2.2、常用注解的主要参数 3、缓存注解上 SPEL 表达式可使用的元数据4、入门案例4.1、引入依赖4.2、开启缓存功能4.3、使用缓存4.3.1、新建一个 UserServiceImpl4.3.2、新建一个 UserController 5、工作原理5.1、缓存自动…

Python从0到100(六十二):机器学习实战-预测波士顿房价

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

77寸OLED透明触摸屏有哪些应用场景

说到77寸OLED透明触摸屏&#xff0c;那可真是市场营销中的一大亮点&#xff0c;应用场景多到数不清&#xff01;我这就给你细数几个热门的&#xff1a; 商业展示&#xff1a;这可是77寸OLED透明触摸屏的拿手好戏&#xff01;在高端零售店铺里&#xff0c;它可以作为陈列窗口&am…

大模型之大模型压缩(量化、剪枝、蒸馏、低秩分解),推理(vllm)

目录 前言 一、模型量化&#xff08;quantization&#xff09; 1. 量化概念 2. 模型量化优点 3. 什么情况下应该/不应该使用模型量化 4. 落地挑战 5. 量化方法 5.1 量化训练(Quant Aware Training, QAT) 原理 [伪量化节点&#xff08;fake quant&#xff09;](https://blog.csd…

​通用代码生成器典型应用场景​

​通用代码生成器典型应用场景​ 1. 通用代码生成器简介 通用代码生成器或称动词算子式通用代码生成器&#xff0c;是一系列各种语言的易用的整站式代码生成器。其根本原理是把方法分解成动词算子和域对象的笛卡儿积。根据动词算子式代码生成器的基本原理。所有方法&#xff…

[uni-app]小兔鲜-08云开发

uniCloud可以通过JS开发服务端,包含云数据库, 云函数, 云存储等功能, uniCloud可结合 uni-ui 组件库使用 效果展示: <picker>城市选择组件不支持h5端和APP端, 所以我们使用 <uni-data-picker>组件进行兼容处理 <uni-data-picker>的数据使用云数据库的数据 云…

项目——超级马里奥——Day(2)

争取今天晚上能搞一半啊&#xff0c;啊啊啊啊&#xff0c;感觉事多的忙不过来 设计思路&#xff1a; 1&#xff09;创建并完成常量类 ------->一张图片的情况 先完成对图片的封装------>把图片加载一遍 &#xff08;老实说&#xff0c;我也不太知道为什么&#xff0…

Stable Diffusion整合包与手动本地部署结合内网穿透远程AI绘画!

前言 文章目录 前言1. 本地部署Stable Diffusion Web UI 1.1 整合包安装1.2 手动安装Stable Diffusion Web UI 2. 安装Cpolar内网穿透3. 实现公网访问Stable Diffusion Web UI4. 固定Stable Diffusion Web UI 公网地址 &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学…

六自由度机械重力补偿控制

1.动力学方程 六自由度机械臂动力学方程形式如下&#xff1a; 进行重力补偿&#xff0c;就是在驱动力矩中对重力G进行补偿&#xff0c;从而消除重力的影响&#xff0c;这样就能够在进行闭环控制的时候避免重力影响带来的大超调问题&#xff0c;使得机器人更好的实现轨迹跟踪控…

(附源码)基于springboot的“我来找房”微信小程序的设计与实现-计算机毕设 23157

基于springboot的“我来找房”微信小程序的设计与实现 摘要 随着移动互联网的快速发展&#xff0c;微信小程序作为一种轻量级的应用程序形式&#xff0c;已经成为人们日常生活的重要组成部分。为了满足广大用户在租房方面的需求&#xff0c;本文设计并实现了一个基于SpringBoot…

FredNormer: 非平稳时间序列预测的频域正则化方法

时间序列预测是一个具有挑战性的任务,尤其是在处理非平稳数据时。现有的基于正则化的方法虽然在解决分布偏移问题上取得了一定成功但仍存在局限性。这些方法主要在时间域进行操作,可能无法充分捕捉在频域中更明显的动态模式,从而导致次优的结果。 FredNormer论文的研究目的主要…

【C++】认识匿名对象

文章目录 目录 文章目录前言一、对匿名对象的解读二、匿名对象的对象类型三、匿名对象的使用总结 前言 在C中&#xff0c;匿名对象是指在没有呗命名的情况下创建的临时对象。它们通常在单个语句中执行一系列操作或调用某个函数&#xff0c;并且不需要将结果存放进变量中。 匿名…

Oracle登录报错-ORA-01017: invalid username/password;logon denied

接上文&#xff1a;Oracle创建用户报错-ORA-65096: invalid common user or role name 我以为 按照上文在PDB里创建了用户&#xff0c;我以为就可以用PLSQL远程连接了&#xff0c;远程服务器上也安装了对应版本的Oracle客户端&#xff0c;但是我想多了&#xff0c;客户只是新建…

使用Python查找WeChat和QQ的安装路径和文档路径

在日常工作和生活中&#xff0c;我们经常需要查找某些应用程序的安装位置或者它们存储文件的位置。特别是对于像WeChat&#xff08;微信&#xff09;和QQ这样的即时通讯软件&#xff0c;了解它们的文件存储位置可以帮助我们更好地管理我们的聊天记录和共享文件。今天&#xff0…

【Diffusion分割】Cold SegDiffusion:医学图像分割的扩散模型

Cold SegDiffusion: A novel diffusion model for medical image segmentation 摘要&#xff1a; 随着深度学习的发展&#xff0c;扩散模型在医学图像分割任务中表现出了卓越的性能。然而&#xff0c;传统的分割扩散模型通常采用随机高斯噪声生成分割掩膜&#xff0c;导致分割…

Java建筑行业智能化管理系统源码,PC端、手机端、大屏端源码,智慧工地管理平台源码,智慧建设平台 智慧住建平台

智慧工地平台全套源码合作 智慧工地是指运用现代信息技术&#xff0c;如物联网&#xff08;IoT&#xff09;、大数据、人工智能&#xff08;AI&#xff09;、云计算、移动互联网等&#xff0c;对传统建筑工地进行智能化改造和管理的新型工地。它通过高度集成的系统和设备&#…

NIO实现聊天室之:一切都要从网络编程的基础开始聊起!

一、写在开头 大家好,Build哥回来啦!停更了大概2个月之久,之前有段时间去写小说去了,后来又因为公司活太多,牛马干的太投入,就拉下了博客的更新,国庆节期间,难得的闲下来,准备回归老本行啦。 大致的翻看了一下之前更新的内容,已经写到了Java的IO部分,作为网络传输…