当前位置: 首页 > 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;回车后应当有版…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...