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

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

React---day11

14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store&#xff1a; 我们在使用异步的时候理应是要使用中间件的&#xff0c;但是configureStore 已经自动集成了 redux-thunk&#xff0c;注意action里面要返回函数 import { configureS…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

R 语言科研绘图第 55 期 --- 网络图-聚类

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

C++实现分布式网络通信框架RPC(2)——rpc发布端

有了上篇文章的项目的基本知识的了解&#xff0c;现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...

基于Uniapp的HarmonyOS 5.0体育应用开发攻略

一、技术架构设计 1.混合开发框架选型 &#xff08;1&#xff09;使用Uniapp 3.8版本支持ArkTS编译 &#xff08;2&#xff09;通过uni-harmony插件调用原生能力 &#xff08;3&#xff09;分层架构设计&#xff1a; graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...