当前位置: 首页 > news >正文

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 自绘表盘

文章目录 效果图代码 效果图 代码 代码没什么好说的&#xff0c;直接上源码.h #pragma once#include <QWidget> #include <QPainter> #include <QResizeEvent> #include <QtMath> #include <QCoreApplication>class DialPlateWidget : public …...

数据科学与数据工程:两者的区别与交集

&#x1f496; 欢迎来到我的博客&#xff01; 非常高兴能在这里与您相遇。在这里&#xff0c;您不仅能获得有趣的技术分享&#xff0c;还能感受到轻松愉快的氛围。无论您是编程新手&#xff0c;还是资深开发者&#xff0c;都能在这里找到属于您的知识宝藏&#xff0c;学习和成长…...

MAC AndroidStudio模拟器无网络

先确认PC端是正常访问网络的&#xff1b; 模拟器端修改Wifi设置&#xff1a;设置 - 网络和互联网 - WALN设置 按照上图修改&#xff1b; IP设置&#xff1a;从DHCP修改为静态&#xff0c;IP地址&#xff1a;10.0.2.16 &#xff0c;网关&#xff1a;10.0.2.2 &#xff0c; DNS…...

PHP语言的多线程编程

PHP语言的多线程编程 引言 在现代Web开发中&#xff0c;PHP以其简洁和易用性广受欢迎。它常用于构建动态网站和应用程序。然而&#xff0c;PHP本身是单线程的&#xff0c;这意味着它在处理多个任务时可能会受到性能限制。随着互联网的发展&#xff0c;对高并发、高可用性和实…...

当自动包布机遇上Profinet转ModbusTCP网关,“妙啊”,工业智能“前景无限

在自动化控制技术日新月异的当下&#xff0c;Profinet与ModbusTCP这两种协议在工业通信领域占据着举足轻重的地位。ModbusTCP是基于以太网的串行通信协议&#xff0c;而Profinet则是依托工业以太网的现场总线协议。它们在数据传输速度、实时性表现以及兼容性等方面各具特色。不…...

浅析大语言模型安全和隐私保护国内外标准和政策

过去两年&#xff0c;大模型技术已经普及并逐步渗透到各行各业&#xff0c;2025年注定是大模型应用井喷式发展的一年&#xff0c;AI在快速发展的同时&#xff0c;其带来的安全风险也逐渐凸显。人工智能系统的安全性和隐私保护已经成为社会关注的重点。 附下载&#xff1a;600多…...

OpenCV相机标定与3D重建(54)解决透视 n 点问题(Perspective-n-Point, PnP)函数solvePnP()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 根据3D-2D点对应关系找到物体的姿态。 cv::solvePnP 是 OpenCV 库中的一个函数&#xff0c;用于解决透视 n 点问题&#xff08;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启动流程&#xff0c;即springboot-mvc <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.3.0</version> </dependency>环境…...

Rust实现智能助手 - 项目初始化

文章目录 前言环境准备依赖代码运行使用最后 前言 你好&#xff0c;我是醉墨居士&#xff0c;最近准备花一些时间来使用Rust语言实现一个智能助手&#xff0c;希望能够帮助到你。 环境准备 安装Rust语言环境&#xff0c;你可以从官网下载安装包安装。安装Ollama&#xff0c;…...

sparkSQL练习

1.前期准备 &#xff08;1&#xff09;建议先把这两篇文章都看一下吧&#xff0c;然后把这个项目也搞下来 &#xff08;2&#xff09;看看这个任务 &#xff08;3&#xff09;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

目录 一&#xff0c;创建helloworld 1.1 通过图形化 1.2 通过代码 1.3 通过编辑框 1.4 使用按钮 二&#xff0c;对象树 2.1 关于对象树 2.2 演示释放流程 三&#xff0c;乱码问题 3.1 为什么会有乱码问题 3.2 解决乱码问题 四&#xff0c;认识Qt坐标系 五&#xf…...

[创业之路-248]:《华为流程变革:责权利梳理与流程体系建设》华为流程的前端拉动后端,与计算机软件的前端应用与后端程序的类比关系

华为的前端拉动后端模式与计算机前端应用与后端程序的类比关系&#xff0c;虽然两者属于不同的领域&#xff0c;但在某些方面存在有趣的相似性。以下是对这两者的类比关系的详细探讨&#xff1a; 一、华为的前端拉动后端模式 定义与特点&#xff1a; 华为的前端拉动后端模式是…...

汇总统计数据--SQL中聚集函数的使用

目录 1、为什么需要汇总数据 2、聚集函数 &#xff08;1&#xff09;AVG函数 &#xff08;2&#xff09;COUNT函数 &#xff08;3&#xff09;MAX和MIN函数 &#xff08;4&#xff09;SUM函数 3、聚集不同值--DISTINCT 4、组合聚集函数 5、小结 博主用的是mysql8 DBMS…...

【C盘清理】C盘清理工具、Unity缓存文件转移

链接: https://pan.baidu.com/s/1yE_7qF741o4NmBIsrd3XzA?pwdbwnn CCleaner 用于清理磁盘垃圾 勾选你要分析的选项&#xff0c;点击分析&#xff0c;分析完毕后&#xff0c;点击清理。 主要别清错东西了。&#xff08;可以不要勾选网络缓存、网络记录相关的选项&#xff0…...

C# 迭代,递归,回调--13

目录 一.迭代 迭代器示例: 关键点: 优势: 二.递归 递归示例: 关键点: 优势: 注意: 三.回调 回调示例: 关键点: 优势: 应用场景: 4.三种模式的特点对比: 迭代: 递归: 回调: 一.迭代 在C#中迭代通常指重复执行一系列指令 在C#中,迭代器是一种特殊的结构,允许…...

海康大数据面试题及参考答案

请详细描述 YARN 提交程序的流程。 YARN(Yet Another Resource Negotiator)是一个资源管理系统,用于管理集群中的计算资源。以下是在 YARN 中提交程序的详细流程: 首先是客户端准备阶段。用户编写好应用程序,这个程序可以是 MapReduce、Spark 或者其他基于 YARN 的计算框架…...

软件测试 —— 自动化测试(Selenium)

软件测试 —— 自动化测试&#xff08;Selenium&#xff09; 什么是SeleniumPython安装Selenium1.安装webdirver-manager2.安装Selenium 写一个简单用例CSS_SELECTOR和XPATH浏览器快速定位页面元素浏览器的前进&#xff08;forward&#xff09;&#xff0c;后退&#xff08;bac…...

华为2024嵌入式研发面试题

01 你认为最好的排序算法是什么&#xff1f; 在实际的编程中&#xff0c;最好的排序算法要根据实际需求和数据规模来选择&#xff0c;因为每种排序算法都有其优势和劣势。以下是一些常见排序算法及其优缺点&#xff1a; 冒泡排序 冒泡排序是一种简单直观的排序算法&#xff0…...

centos 搭建nginx+配置域名+windows访问

准备工作&#xff1a;一个完整的centos环境&#xff0c;nginx安装包(可以从官网下载)nginx: download 一&#xff1a;centos可能有精简版&#xff0c;部分环境没有相关依赖包&#xff0c; 需要检查以下项&#xff1a; 1.gcc检查&#xff1a;gcc -v&#xff08;回车后应当有版…...

如何在3小时内构建你的第一个炉石传说AI机器人?Hearthrock终极指南

如何在3小时内构建你的第一个炉石传说AI机器人&#xff1f;Hearthrock终极指南 【免费下载链接】hearthrock Hearthstone Bot Engine 项目地址: https://gitcode.com/gh_mirrors/he/hearthrock Hearthrock是一个革命性的炉石传说AI引擎&#xff0c;专为人工智能研究者和…...

PyTorch 2.8镜像精彩案例分享:使用AnimateDiff生成动漫风格短视频合集

PyTorch 2.8镜像精彩案例分享&#xff1a;使用AnimateDiff生成动漫风格短视频合集 1. 开箱即用的高性能深度学习环境 PyTorch 2.8深度学习镜像为创作者和开发者提供了一个强大的工具箱&#xff0c;特别适合需要生成高质量视频内容的场景。这个经过深度优化的环境基于RTX 4090…...

大规模数据清洗效率提升300%的Polars 2.0实战方案(内存泄漏避坑全图谱)

第一章&#xff1a;Polars 2.0大规模数据清洗的范式跃迁 Polars 2.0 不再是 Pandas 的轻量替代品&#xff0c;而是一次面向现代硬件与真实数据工程场景的底层重构。其核心跃迁体现在三重解耦&#xff1a;计算图与执行引擎分离、内存布局与逻辑 Schema 解耦、以及 I/O 层与处理层…...

别再搞混了!海康相机Bayer、Mono、YUV格式详解与选型避坑指南

工业相机图像格式全解析&#xff1a;从Bayer到YUV的实战选型策略 第一次接触工业相机参数表时&#xff0c;看到BayerRG8、Mono12 Packed、YUV422这些术语是不是感觉像在读天书&#xff1f;去年我在自动化检测项目上就曾因为选错图像格式&#xff0c;导致整套视觉算法推倒重来。…...

快速验证模型服务:AutoGen Studio中连接vLLM部署的Qwen3-4B

快速验证模型服务&#xff1a;AutoGen Studio中连接vLLM部署的Qwen3-4B 1. 环境准备与快速部署 1.1 镜像启动与基础检查 首先确保已成功启动AutoGen Studio镜像&#xff0c;该镜像已预置vLLM部署的Qwen3-4B-Instruct-2507模型服务。验证模型服务是否正常运行&#xff1a; c…...

Omni-Vision Sanctuary 集成 MySQL 数据库:自动化图像元数据管理与检索方案

Omni-Vision Sanctuary 集成 MySQL 数据库&#xff1a;自动化图像元数据管理与检索方案 1. 场景痛点与解决方案 数字内容创作领域正面临一个普遍挑战&#xff1a;随着AI生成图像的爆发式增长&#xff0c;如何高效管理海量图片资产成为棘手问题。某电商设计团队负责人曾向我们…...

终极指南:如何将danger-js与Webpack集成实现自动化代码审查

终极指南&#xff1a;如何将danger-js与Webpack集成实现自动化代码审查 【免费下载链接】danger-js ⚠️ Stop saying "you forgot to …" in code review 项目地址: https://gitcode.com/gh_mirrors/da/danger-js Danger JS是一个强大的自动化代码审查工具&a…...

Hashids终极指南:BCMath与GMP数学扩展性能深度对比

Hashids终极指南&#xff1a;BCMath与GMP数学扩展性能深度对比 【免费下载链接】hashids A small PHP library to generate YouTube-like ids from numbers. Use it when you dont want to expose your database ids to the user. 项目地址: https://gitcode.com/gh_mirrors/…...

IBM Plex字体家族全攻略:企业级开源字体的应用与实践

IBM Plex字体家族全攻略&#xff1a;企业级开源字体的应用与实践 【免费下载链接】plex The package of IBM’s typeface, IBM Plex. 项目地址: https://gitcode.com/gh_mirrors/pl/plex 企业级字体解决方案的价值解析 在数字产品设计中&#xff0c;字体作为视觉传达的…...

学习框架和推理引擎有什么区别

​​​​​​学习框架和推理引擎通常分别应用在 AI 大模型的训练和推理 &#xff08;运行&#xff09;阶段。模型的核心任务是从大量数据中学习规律&#xff0c;完成特定预测或者生成任务&#xff0c;前者即“模型训练”&#xff0c;后者即“模型运行”。在模型训练时&#xff…...