C++ QT 自绘表盘
文章目录
- 效果图
- 代码
效果图
代码
- 代码没什么好说的,直接上源码
- .h
#pragma once#include <QWidget>
#include <QPainter>
#include <QResizeEvent>
#include <QtMath>
#include <QCoreApplication>class DialPlateWidget : public QWidget
{Q_OBJECTQ_PROPERTY(double minValue READ getMinValue WRITE setMinValue USER true)Q_PROPERTY(double maxValue READ getMaxValue WRITE setMaxValue USER true)Q_PROPERTY(double value READ getValue WRITE setValue USER true)public:explicit DialPlateWidget(QWidget *parent = nullptr);// 获取和设置最小值double getMinValue() const;void setMinValue(double minValue);// 获取和设置最大值double getMaxValue() const;void setMaxValue(double maxValue);/// @brief 设置当前值void setValue(double ivalue);double getValue() const;/// @brief 设置标题和单位/// @param title/// @param unitvoid setContent(QString title, QString unit = QString());QSize sizeHint() const override;QSize minimumSizeHint() const override;~DialPlateWidget();private:void paintEvent(QPaintEvent *event) override;void drawBg(QPainter *painter);void drawDial(QPainter *painter);void drawScaleNum(QPainter *painter);void drawIndicator(QPainter *painter);void drawText(QPainter *painter);private:QString unit; // 单位QString title; // 名称const static int radius; // 半径double maxv; // 最小值double minv; // 最大值double percent = 0; // 百分比int m_refSize = 200; // 刻度线长度int Angle = 45; // 刻度线角度double m_value = 0; // 当前值
};
- cpp
#include "dialPlateWidget.h"const int DialPlateWidget::radius = 100;DialPlateWidget::DialPlateWidget(QWidget *parent) : QWidget(parent)
{maxv = 200;minv = 0;this->installEventFilter(this);m_refSize = 2.5 * radius;
}DialPlateWidget::~DialPlateWidget()
{
}void DialPlateWidget::setValue(double ivalue)
{// 确保值在最小值和最大值之间if (ivalue < minv){ivalue = minv;}else if (ivalue > maxv){ivalue = maxv;}m_value = ivalue;percent = (ivalue - minv) / (maxv - minv) * 100;update();
}double DialPlateWidget::getValue() const
{return minv + percent * (maxv - minv) / 100; // 根据百分比计算实际值
}QSize DialPlateWidget::sizeHint() const
{return QSize(m_refSize, m_refSize);
}QSize DialPlateWidget::minimumSizeHint() const
{return QSize(30, 10);
}void DialPlateWidget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);// 计算缩放比例,确保仪表盘适应Widget大小float scale = qMin(width(), height()) / (float)m_refSize;painter.scale(scale, scale);// 设置坐标原点为中心点painter.translate(width() / (2 * scale), height() / (2 * scale));// 绘制背景、刻度线、刻度数字、指针和文字drawBg(&painter);drawDial(&painter);drawScaleNum(&painter);drawIndicator(&painter);drawText(&painter);QWidget::paintEvent(event);
}void DialPlateWidget::drawBg(QPainter *painter)
{int r = radius;painter->save();painter->setPen(Qt::NoPen);painter->setBrush(QColor(172, 172, 172));painter->drawEllipse(-r, -r, r * 2, r * 2);r = radius * 0.9;painter->setBrush(QColor(40, 40, 40));painter->setPen(Qt::NoPen);painter->drawEllipse(-r, -r, r * 2, r * 2);painter->restore();
}void DialPlateWidget::drawDial(QPainter *painter)
{int r = radius * 0.85;double lineWidth = 1;painter->save();painter->rotate(Angle);double rotate = (double)(360 - (Angle * 2)) / 100;for (int i = 0; i <= 100; i++){QColor color = QColor(84, 84, 84);if (i <= 30)color = QColor(250, 0, 0);if (i > 30)color = QColor(0, 255, 0, 255);if ((i % 10) == 0){painter->setPen(QPen(color, 4.2 * lineWidth));painter->drawLine(0, r, 0, r / 1.2);}else if ((i % 2) == 0){painter->setPen(QPen(color, 1 * lineWidth));painter->drawLine(0, r, 0, r / 1.1);}painter->rotate(rotate);}painter->restore();
}void DialPlateWidget::drawScaleNum(QPainter *painter)
{painter->save();int r = (int)(radius * 0.6); // 增加半径,使刻度数字更远离中心painter->setFont(QFont("Arial", 12));painter->setPen(QPen(QColor(255, 255, 255)));QFontMetricsF fm = QFontMetricsF(painter->font());// 计算五个标值的间隔double valueRange = maxv - minv;double valueStep = valueRange / 4.0; // 四个间隔,五个标值double angleStep = (360.0 - Angle * 2) / 4.0; // 对应的角度间隔for (int i = 0; i <= 4; ++i){double value = minv + i * valueStep; // 当前标值double angle = 90 + Angle + i * angleStep; // 当前标值对应的角度float angleArc = (int(angle) % 360) * 3.14 / 180; // 转换为弧度int x = r * cos(angleArc);int y = r * sin(angleArc);QString speed = QString::number(value);int w = (int)fm.width(speed);int h = (int)fm.height();x = x - w / 2;y = y + h / 4; // 调整文本位置painter->drawText(QPointF(x, y), speed);}painter->restore();
}void DialPlateWidget::drawIndicator(QPainter *painter)
{painter->save();QPolygon pts;int r = radius * 0.6;pts.setPoints(3, -2, 0, 2, 0, 0, r);double angle = Angle + (360.0 - 2 * Angle) * (percent / 100.0);painter->rotate(angle);// 绘制指针QRadialGradient haloGradient(0, 0, 60, 0, 0); // 辐射渐变,内部填充颜色haloGradient.setColorAt(0, QColor(100, 100, 100));haloGradient.setColorAt(1, QColor(250, 50, 50)); // redpainter->setPen(QColor(250, 150, 150)); // 边框颜色painter->setBrush(haloGradient);painter->drawConvexPolygon(pts);// 绘制中心圆圈QRadialGradient radial(0, 0, 14); // 渐变radial.setColorAt(0.0, QColor(100, 100, 100));radial.setColorAt(1.0, QColor(250, 50, 50));painter->setPen(Qt::NoPen); // 填满没有边界painter->setBrush(radial);painter->drawEllipse(-7, -7, 14, 14);painter->restore();
}void DialPlateWidget::drawText(QPainter *painter)
{painter->save();painter->setFont(QFont("Arial", 8));painter->setPen(QPen(QColor(255, 255, 255)));QFontMetricsF fm = QFontMetricsF(painter->font());QString speed = title + QString::number(m_value) + unit;int w = (int)fm.width(speed);painter->drawText(QPointF(-w / 2, (int)(0.7 * radius)), speed);painter->restore();
}void DialPlateWidget::setContent(QString title, QString unit)
{this->unit = unit;this->title = title;update(); // 更新显示
}double DialPlateWidget::getMinValue() const
{return minv;
}void DialPlateWidget::setMinValue(double minValue)
{minv = minValue;
}double DialPlateWidget::getMaxValue() const
{return maxv;
}void DialPlateWidget::setMaxValue(double maxValue)
{maxv = maxValue;
}
相关文章:

C++ QT 自绘表盘
文章目录 效果图代码 效果图 代码 代码没什么好说的,直接上源码.h #pragma once#include <QWidget> #include <QPainter> #include <QResizeEvent> #include <QtMath> #include <QCoreApplication>class DialPlateWidget : public …...

数据科学与数据工程:两者的区别与交集
💖 欢迎来到我的博客! 非常高兴能在这里与您相遇。在这里,您不仅能获得有趣的技术分享,还能感受到轻松愉快的氛围。无论您是编程新手,还是资深开发者,都能在这里找到属于您的知识宝藏,学习和成长…...

MAC AndroidStudio模拟器无网络
先确认PC端是正常访问网络的; 模拟器端修改Wifi设置:设置 - 网络和互联网 - WALN设置 按照上图修改; IP设置:从DHCP修改为静态,IP地址:10.0.2.16 ,网关:10.0.2.2 , DNS…...
PHP语言的多线程编程
PHP语言的多线程编程 引言 在现代Web开发中,PHP以其简洁和易用性广受欢迎。它常用于构建动态网站和应用程序。然而,PHP本身是单线程的,这意味着它在处理多个任务时可能会受到性能限制。随着互联网的发展,对高并发、高可用性和实…...

当自动包布机遇上Profinet转ModbusTCP网关,“妙啊”,工业智能“前景无限
在自动化控制技术日新月异的当下,Profinet与ModbusTCP这两种协议在工业通信领域占据着举足轻重的地位。ModbusTCP是基于以太网的串行通信协议,而Profinet则是依托工业以太网的现场总线协议。它们在数据传输速度、实时性表现以及兼容性等方面各具特色。不…...

浅析大语言模型安全和隐私保护国内外标准和政策
过去两年,大模型技术已经普及并逐步渗透到各行各业,2025年注定是大模型应用井喷式发展的一年,AI在快速发展的同时,其带来的安全风险也逐渐凸显。人工智能系统的安全性和隐私保护已经成为社会关注的重点。 附下载:600多…...
OpenCV相机标定与3D重建(54)解决透视 n 点问题(Perspective-n-Point, PnP)函数solvePnP()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 根据3D-2D点对应关系找到物体的姿态。 cv::solvePnP 是 OpenCV 库中的一个函数,用于解决透视 n 点问题(Perspective-n-Po…...

Chatper 4: Implementing a GPT model from Scratch To Generate Text
文章目录 4 Implementing a GPT model from Scratch To Generate Text4.1 Coding an LLM architecture4.2 Normalizing activations with layer normalization4.3 Implementing a feed forward network with GELU activations4.4 Adding shortcut connections4.5 Connecting at…...
spring-mvc源码分析v3.3.0
分析下springboot内嵌tomcat启动流程,即springboot-mvc <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.3.0</version> </dependency>环境…...
Rust实现智能助手 - 项目初始化
文章目录 前言环境准备依赖代码运行使用最后 前言 你好,我是醉墨居士,最近准备花一些时间来使用Rust语言实现一个智能助手,希望能够帮助到你。 环境准备 安装Rust语言环境,你可以从官网下载安装包安装。安装Ollama,…...

sparkSQL练习
1.前期准备 (1)建议先把这两篇文章都看一下吧,然后把这个项目也搞下来 (2)看看这个任务 (3)score.txt student_id,course_code,score 108,3-105,99 105,3-105,88 107,3-105,77 105,3-245,87 1…...

QT跨平台应用程序开发框架(2)—— 初识QT
目录 一,创建helloworld 1.1 通过图形化 1.2 通过代码 1.3 通过编辑框 1.4 使用按钮 二,对象树 2.1 关于对象树 2.2 演示释放流程 三,乱码问题 3.1 为什么会有乱码问题 3.2 解决乱码问题 四,认识Qt坐标系 五…...
[创业之路-248]:《华为流程变革:责权利梳理与流程体系建设》华为流程的前端拉动后端,与计算机软件的前端应用与后端程序的类比关系
华为的前端拉动后端模式与计算机前端应用与后端程序的类比关系,虽然两者属于不同的领域,但在某些方面存在有趣的相似性。以下是对这两者的类比关系的详细探讨: 一、华为的前端拉动后端模式 定义与特点: 华为的前端拉动后端模式是…...
汇总统计数据--SQL中聚集函数的使用
目录 1、为什么需要汇总数据 2、聚集函数 (1)AVG函数 (2)COUNT函数 (3)MAX和MIN函数 (4)SUM函数 3、聚集不同值--DISTINCT 4、组合聚集函数 5、小结 博主用的是mysql8 DBMS…...

【C盘清理】C盘清理工具、Unity缓存文件转移
链接: https://pan.baidu.com/s/1yE_7qF741o4NmBIsrd3XzA?pwdbwnn CCleaner 用于清理磁盘垃圾 勾选你要分析的选项,点击分析,分析完毕后,点击清理。 主要别清错东西了。(可以不要勾选网络缓存、网络记录相关的选项࿰…...
C# 迭代,递归,回调--13
目录 一.迭代 迭代器示例: 关键点: 优势: 二.递归 递归示例: 关键点: 优势: 注意: 三.回调 回调示例: 关键点: 优势: 应用场景: 4.三种模式的特点对比: 迭代: 递归: 回调: 一.迭代 在C#中迭代通常指重复执行一系列指令 在C#中,迭代器是一种特殊的结构,允许…...
海康大数据面试题及参考答案
请详细描述 YARN 提交程序的流程。 YARN(Yet Another Resource Negotiator)是一个资源管理系统,用于管理集群中的计算资源。以下是在 YARN 中提交程序的详细流程: 首先是客户端准备阶段。用户编写好应用程序,这个程序可以是 MapReduce、Spark 或者其他基于 YARN 的计算框架…...

软件测试 —— 自动化测试(Selenium)
软件测试 —— 自动化测试(Selenium) 什么是SeleniumPython安装Selenium1.安装webdirver-manager2.安装Selenium 写一个简单用例CSS_SELECTOR和XPATH浏览器快速定位页面元素浏览器的前进(forward),后退(bac…...
华为2024嵌入式研发面试题
01 你认为最好的排序算法是什么? 在实际的编程中,最好的排序算法要根据实际需求和数据规模来选择,因为每种排序算法都有其优势和劣势。以下是一些常见排序算法及其优缺点: 冒泡排序 冒泡排序是一种简单直观的排序算法࿰…...

centos 搭建nginx+配置域名+windows访问
准备工作:一个完整的centos环境,nginx安装包(可以从官网下载)nginx: download 一:centos可能有精简版,部分环境没有相关依赖包, 需要检查以下项: 1.gcc检查:gcc -v(回车后应当有版…...
类型别名与类型自动推导
类型别名与类型的自动推导 类型别名 为什么要引入类型别名? 为了给类型赋予特殊含义或便于使用 典型用途 (1)增强代码可移植性 例如:size_t (在不同系统中可能是unsigned int 或 unsigned long) 首先是…...

快速上手 Metabase:从安装到高级功能实战
文章目录 1. 引言:Metabase——轻量级的数据分析工具🎯 学完本教程你能掌握: 2. 安装 Metabase:本地部署实操2.1 环境准备2.2 使用 Docker 安装 Metabase2.3 初始化设置2.4 连接外部数据库 3. 第一个数据探索:5分钟创建…...
学习记录aigc
1、DIT https://zhuanlan.zhihu.com/p/683612528 DiT最大的创新点是将Transformer引入到了扩散模型中,并完全抛弃了CNN。但是DiT并不是第一个引入Transformer的,例如之前的U-ViT,UniDiffuser等都尝试了将Transformer引入到扩散模型中。至于…...

Ctrl+R 运行xxx.exe,发现有如下问题.
CtrlR 运行xxx.exe,发现有如下问题. (1)找不到Qt5Core.all,Qt5Cored.dll,Qt5Gui.dll,Qt5Guid.dll,Qt5Widgets.all,Qt5Widgetsd.dll? (2)之后找不到libwinpthread-1.dll 从这个目录拷贝相应的库到运行xx.exe目录下 方法二:将库路径添加到系统PATH环境变量里: 在Path中添加路…...
[蓝桥杯]采油
采油 题目描述 LQ 公司是世界著名的石油公司,为世界供应优质石油。 最近,LQ 公司又在森林里发现了一大片区域的油田,可以在这个油田中开采 nn 个油井。 LQ 公司在这 nn 个油井之间修建了 n−1n−1 条道路,每条道路连接两个油井…...

开始在本地部署自己的 Gitea 服务器
0.简介 在软件开发和团队协作中,代码管理是至关重要的环节。笔者一直使用gitblit管理自己的仓库。然鹅,这个软件已经很久没有更新了。经过多方考察,发现Gitea 是一款轻量级的开源代码托管平台,具有易于部署、资源占用少、功能丰富…...
撰写脚本,通过发布/joint_states话题改变机器人在Rviz中的关节角度
撰写脚本,通过发布/joint_states话题改变机器人在Rviz中的关节角度 提问 为我写一个改变关节base_spherical_center_high_joint角度的python脚本吧。适用于ROS2的humble 回答 下面是一个适用于 ROS 2 Humble 的 Python 脚本,它会以指定频率持续发布 …...
Kerberos面试内容整理-在 Linux/Windows 中的 Kerberos 实践
Windows 实践: 在Windows环境中,Kerberos 几乎是无形融合的。用户使用域账号登录计算机时,实际上就完成了Kerberos的AS认证并获取TGT;此后的资源访问(如共享文件夹、打印机、数据库等)都会自动使用Kerberos进行验证,而无需用户干预。Windows通过LSASS进程维护和缓存用户…...

SpringCloud学习笔记-2
说明:来源于网络,如有侵权请联系我删除 1.提问:如果注册中心宕机,远程调用还能成功吗 答:当微服务发起请求时,会向注册中心请求所有的微服务地址,然后在向指定的微服务地址发起请求。在设计实…...

postman基础
前言 本次 Chat 将结合业界广为推崇和使用的 RestAPI 设计典范 Github API,详细介绍 Postman 接口测试工具的使用方法和实战技巧。 在开始这个教程之前,先聊一下为什么接口测试在现软件行业如此重要? 为什么我们要学习 Postman?…...