文章的目的为了记录使用C++ 进行QT Widget 开发学习的经历。临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
 
相关链接:

开源 C++ QT Widget 开发(一)工程文件结构-CSDN博客

开源 C++ QT Widget 开发(二)基本控件应用-CSDN博客

开源 C++ QT Widget 开发(三)图表--波形显示器-CSDN博客

开源 C++ QT Widget 开发(四)文件--二进制文件查看编辑-CSDN博客

 开源 C++ QT Widget 开发(五)通讯--串口调试-CSDN博客

开源 C++ QT Widget 开发(六)通讯--TCP调试-CSDN博客

开源 C++ QT Widget 开发(七)线程--多线程及通讯-CSDN博客

开源 C++ QT Widget 开发(八)网络--Http文件下载-CSDN博客

开源 C++ QT Widget 开发(九)图表--仪表盘-CSDN博客

推荐链接:

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

本章主要内容:基于 Qt框架实现的仪表盘控件。

目录:

1.源码分析

2.所有源码

3.效果演示

一、核心源码分析

1. 外观特点
颜色方案:采用黑色背景与亮蓝色(青绿色)的刻度、文字和指针

警告区域:使用橙红色半透明区域标识超速警告

数字显示:底部有数字显示当前值和单位

2. 公共接口
这些方法提供了对仪表盘外观和数据的控制。

void setValue(double value);          // 设置当前速度值
void setRange(double min, double max); // 设置量程范围
void setUnits(const QString &units);  // 设置单位
void setWarningValue(double value);   // 设置警告值

3. 几何参数
仪表盘覆盖270度的圆弧范围。

double m_startAngle{135};  // 起始角度(135度 - 左下)
double m_endAngle{360+45}; // 结束角度(405度 - 右下)

4. 实现文件 (dashboard.cpp)
绘制组件:
drawBackground(): 绘制背景和渐变效果

drawWarningZone(): 绘制警告区域

drawTicks(): 绘制刻度和数字

drawNeedle(): 绘制指针

drawDigitalDisplay(): 绘制数字显示

坐标计算:
getTickPosition(): 计算刻度位置

getNeedleEndPoint(): 计算指针端点位置

二、所有源码

1.Dashboard.h文件

#ifndef DASHBOARD_H
#define DASHBOARD_H#include <QWidget>
#include <QTimer>class Dashboard : public QWidget
{Q_OBJECTpublic:explicit Dashboard(QWidget *parent = nullptr);// 公共接口函数void setValue(double value);          // 设置当前速度值void setRange(double min, double max); // 设置量程范围void setUnits(const QString &units);  // 设置单位void setWarningValue(double value);   // 设置警告值double value() const { return m_value; }double minValue() const { return m_minValue; }double maxValue() const { return m_maxValue; }protected:void paintEvent(QPaintEvent *event) override;void resizeEvent(QResizeEvent *event) override;private:void drawBackground(QPainter &painter);void drawTicks(QPainter &painter);void drawNumbers(QPainter &painter);void drawNeedle(QPainter &painter);void drawDigitalDisplay(QPainter &painter);void drawWarningZone(QPainter &painter);// 坐标转换函数QPointF getTickPosition(double value, double length) const;QPointF getNeedleEndPoint() const;// 仪表盘参数double m_value{0};double m_minValue{0};double m_maxValue{260};double m_warningValue{200};QString m_units{"km/h"};// 外观参数// 外观参数 - 亮浅蓝色主题QColor m_backgroundColor{QColor(0, 0, 0)};  // 亮浅蓝色QColor m_scaleColor{QColor(9, 245, 249)};           // 深蓝色刻度//QColor m_needleColor{Qt::red};                    // 红色指针//QColor m_textColor{Qt::white};                    // 黑色文字QColor m_needleColor{QColor(9, 245, 249)};                    // 红色指针QColor m_textColor{QColor(9, 245, 249)};                    // 黑色文字QColor m_warningColor{QColor(255, 69, 0)};        // 橙红色警告//QColor m_digitalBgColor{QColor(240, 240, 240, 220)}; // 浅灰色数字背景QColor m_digitalBgColor{QColor(0, 0, 0)}; // 浅灰色数字背景// 几何参数QRectF m_dialRect;QPointF m_center;double m_radius{0};double m_startAngle{135};  // 起始角度(度)double m_endAngle{360+45};    // 结束角度(度)
};#endif // DASHBOARD_H

2. Dashboard.cpp文件

#include "dashboard.h"
#include <QPainter>
#include <QConicalGradient>
#include <QtMath>
#include <QFontDatabase>
#include <QDebug>
Dashboard::Dashboard(QWidget *parent) : QWidget(parent)
{// 设置默认大小setMinimumSize(300, 300);// 可选:添加字体(确保数字显示美观)int fontId = QFontDatabase::addApplicationFont(":/fonts/digital.ttf");if (fontId == -1) {// 使用系统字体作为备选qDebug() << "Failed to load digital font, using system font";}
}void Dashboard::setValue(double value)
{// 限制值在范围内m_value = qBound(m_minValue, value, m_maxValue);update(); // 触发重绘
}void Dashboard::setRange(double min, double max)
{m_minValue = min;m_maxValue = max;if (m_value > m_maxValue) m_value = m_maxValue;if (m_value < m_minValue) m_value = m_minValue;update();
}void Dashboard::setUnits(const QString &units)
{m_units = units;update();
}void Dashboard::setWarningValue(double value)
{m_warningValue = value;update();
}void Dashboard::paintEvent(QPaintEvent *event)
{Q_UNUSED(event);QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 计算几何参数m_center = rect().center();m_radius = qMin(width(), height()) * 0.4;m_dialRect = QRectF(m_center.x() - m_radius, m_center.y() - m_radius,m_radius * 2, m_radius * 2);// 绘制各个部件drawBackground(painter);drawWarningZone(painter);drawTicks(painter);drawNumbers(painter);drawNeedle(painter);drawDigitalDisplay(painter);
}void Dashboard::resizeEvent(QResizeEvent *event)
{QWidget::resizeEvent(event);update(); // 尺寸变化时重绘
}void Dashboard::drawBackground(QPainter &painter)
{// 绘制外圆painter.setPen(QPen(m_scaleColor, 2));painter.setBrush(m_backgroundColor);painter.drawEllipse(m_dialRect);// 绘制内圆(创建立体感)QRadialGradient gradient(m_center, m_radius);gradient.setColorAt(0, QColor(100, 100, 100));gradient.setColorAt(1, m_backgroundColor);painter.setBrush(gradient);painter.drawEllipse(m_center, m_radius * 0.9, m_radius * 0.9);
}void Dashboard::drawWarningZone(QPainter &painter)
{if (m_warningValue <= m_minValue) return;double warningStartAngle = m_startAngle + (m_warningValue - m_minValue) /(m_maxValue - m_minValue) * (m_endAngle - m_startAngle);QPainterPath path;path.arcMoveTo(m_dialRect, warningStartAngle);path.arcTo(m_dialRect, warningStartAngle, m_endAngle - warningStartAngle);QPen pen(Qt::NoPen);painter.setPen(pen);painter.setBrush(QColor(255, 0, 0, 80)); // 半透明红色painter.drawPath(path);
}void Dashboard::drawTicks(QPainter &painter)
{painter.setPen(QPen(m_scaleColor, 2));// 主刻度(每20单位)for (int i = m_minValue; i <= m_maxValue; i += 20) {if (i > m_maxValue) break;QPointF start = getTickPosition(i, m_radius * 0.85);QPointF end = getTickPosition(i, m_radius * 0.95);painter.drawLine(start, end);}// 次刻度(每10单位)painter.setPen(QPen(m_scaleColor, 1));for (int i = m_minValue; i <= m_maxValue; i += 10) {if (i % 20 == 0) continue; // 跳过主刻度QPointF start = getTickPosition(i, m_radius * 0.9);QPointF end = getTickPosition(i, m_radius * 0.95);painter.drawLine(start, end);}
}void Dashboard::drawNumbers(QPainter &painter)
{painter.setPen(m_textColor);QFont font = painter.font();font.setPointSize(10);font.setBold(true);painter.setFont(font);for (int i = m_minValue; i <= m_maxValue; i += 20) {if (i > m_maxValue) break;QPointF pos = getTickPosition(i, m_radius * 0.75);QRectF textRect(pos.x() - 20, pos.y() - 10, 40, 20);painter.drawText(textRect, Qt::AlignCenter, QString::number(i));}
}void Dashboard::drawNeedle(QPainter &painter)
{QPointF needleEnd = getNeedleEndPoint();// 绘制指针QPen needlePen(m_needleColor, 3);needlePen.setCapStyle(Qt::RoundCap);painter.setPen(needlePen);painter.drawLine(m_center, needleEnd);// 绘制中心圆painter.setPen(Qt::NoPen);painter.setBrush(m_needleColor);painter.drawEllipse(m_center, 5, 5);
}void Dashboard::drawDigitalDisplay(QPainter &painter)
{// 绘制数字显示区域QRectF digitalRect(m_center.x() - 60, m_center.y() + m_radius * 0.3, 120, 40);painter.setPen(Qt::NoPen);painter.setBrush(m_digitalBgColor);painter.drawRoundedRect(digitalRect, 5, 5);// 绘制数字painter.setPen(m_textColor);QFont font = painter.font();font.setPointSize(16);font.setBold(true);painter.setFont(font);QString displayText = QString("%1 %2").arg(m_value, 0, 'f', 0).arg(m_units);painter.drawText(digitalRect, Qt::AlignCenter, displayText);
}QPointF Dashboard::getTickPosition(double value, double length) const
{double angle = m_startAngle + (value - m_minValue) /(m_maxValue - m_minValue) * (m_endAngle - m_startAngle);double radian = qDegreesToRadians(angle);return QPointF(m_center.x() + length * qCos(radian),m_center.y() + length * qSin(radian));
}QPointF Dashboard::getNeedleEndPoint() const
{double angle = m_startAngle + (m_value - m_minValue) /(m_maxValue - m_minValue) * (m_endAngle - m_startAngle);double radian = qDegreesToRadians(angle);return QPointF(m_center.x() + m_radius * 0.7 * qCos(radian),m_center.y() + m_radius * 0.7 * qSin(radian));
}

3.mainwindow.cpp文件

#include "mainwindow.h"
#include "Dashboard.h"
#include <QVBoxLayout>
#include <QSlider>
#include <QLabel>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent)
{// 创建中央部件QWidget *centralWidget = new QWidget(this);setCentralWidget(centralWidget);// 创建布局QVBoxLayout *layout = new QVBoxLayout(centralWidget);// 创建仪表盘Dashboard *dashboard = new Dashboard(this);dashboard->setRange(0, 240);dashboard->setWarningValue(200);dashboard->setValue(60); // 初始值// 创建控制滑块QSlider *slider = new QSlider(Qt::Horizontal);slider->setRange(0, 260);slider->setValue(60);// 连接信号槽connect(slider, &QSlider::valueChanged, dashboard, &Dashboard::setValue);// 添加到布局layout->addWidget(dashboard);layout->addWidget(slider);resize(400, 500);
}MainWindow::~MainWindow()
{
}

三、效果演示

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

怎么为服务器设置或重置服务器密码?

创建服务器后&#xff0c;您可以设置服务器的登录密码&#xff0c;如果你忘记了密码&#xff0c;可以重新设置实例的密码。本文讲一下如何重置阿里云服务器密码。使用限制&#xff1a;离线重置密码仅支持在控制台设置或重置服务器管理员账号的密码。•Windows 实例的默认用户名…

【线性代数入门 | 那忘算8】洛谷P3389 高斯消元(内附行列式教学)

想了想还是单开了一篇&#xff0c;数学王子值得&#xff01; 专栏指路&#xff1a;《再来一遍一定记住的算法&#xff08;那些你可能忘记了的算法&#xff09;》 前置知识&#xff1a; 矩阵&#xff1a;数的集合&#xff0c;一般是方程的系数。 题面&#xff1a; 洛谷P3389 …

GEM5学习(3):如何快速创建一个组件

通过一个图并行计算的测试用例&#xff0c;来学习如何快速构建一个目标组件 其核心思想是通过继承现有组件再拓展自定义参数 创建脚本 如何创建脚本&#xff0c;具体还可以看官方说明&#xff1a;gem5: Adding cache to configuration script mkdir configs/tutorial/part1/…

数据血缘中的图数据库如何选择

Neo4j 和 ArangoDB 都是非常优秀的图数据库&#xff0c;但它们的设计哲学、核心架构和适用场景有显著的区别。 简单来说&#xff0c;核心区别在于&#xff1a; Neo4j 是原生图数据库&#xff0c;专为处理图数据和图查询而设计和优化。ArangoDB 是多模型数据库&#xff0c;同时支…

第27章学习笔记|学无止境:从“会用命令”到“会做工具”的进阶路线

第27章学习笔记|学无止境:从“会用命令”到“会做工具”的进阶路线 你已经能用 PowerShell 解决很多日常问题了。接下来最重要的,就是把零散命令升级为可复用的工具,并在真实场景中不断打磨。 一、为什么下一步是“工具化(Toolmaking)” 当任务开始“重复、多人用、可移…

C++编程语言:标准库:第37章——正则表达式(Bjarne Stroustrup)

第 37章 正则表达式(Regular Expressions) 目录 37.1 正则表达式(规范表达式)(Regular Expressions) 37.1.1 正则表达式相关符号(Regular Express Notation) 37.2 regex 37.2.1 匹配结果(Match Results) 37.2.2 格式化(Formatting) 37.3 正则表达式函数 37.3.1 …

sciml包scixgboost函数发布,轻松完成机器学习xgboost分析

Xgboost是Boosting算法的其中一种&#xff0c;Boosting算法的思想是将许多弱分类器集成在一起&#xff0c;形成一个强分类器。因为Xgboost是一种提升树模型&#xff0c;所以它是将许多树模型集成在一起&#xff0c;形成一个很强的分类器。 我目前整合了多个R包&#xff0c;编写…

Ubuntu中配置JMmeter工具

1、检查是否已安装Java 环境java -version若未安装&#xff0c;执行以下命令安装 OpenJDKsudo apt update sudo apt install openjdk-11-jdk # 或 openjdk-17-jdk2、用wget直接下载JMeter压缩包wget https://dlcdn.apache.org/jmeter/binaries/apache-jmeter-5.6.3.tgz将下载的…

LeetCode 925.长按键入

你的朋友正在使用键盘输入他的名字 name。偶尔&#xff0c;在键入字符 c 时&#xff0c;按键可能会被长按&#xff0c;而字符可能被输入 1 次或多次。 你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字&#xff08;其中一些字符可能被长按&#xff09;&#…

9.3 模拟

lc190 颠倒二进制ret (ret << 1) (n >> i & 1);class Solution { public:uint32_t reverseBits(uint32_t n) {uint32_t ret 0;for (int i 0; i < 32; i)ret (ret << 1) (n >> i & 1);return ret;} };lc14 flag checkclass Solution {…

esp32小智ai对话机器人

ESP-IDF 环境搭建与问题解决 下载与安装 ESP-IDF 官方下载地址&#xff1a;https://dl.espressif.com/dl/esp-idf建议使用稳定版本&#xff0c;避免开发版可能存在的兼容性问题 中文编码问题解决方案 $env:PYTHONIOENCODING "utf-8" $env:PYTHONUTF8 "1&q…

11.类与对象

目录 1. 创建类与对象示例 1.1 __init__ 初始化器: 1.2 __new__构造器 1.3 什么时候需要重写 __new__? 1.4 init和new对比 2. 属性 2.1 实例属性 2.2 类属性 3. 作用域命名约定 3.1 非公共属性 3.2 公共属性 3.3 名称修饰 3.4 一眼看懂三种“可见性” 4. 方法 …

【js】Promise.try VS try-catch

前言JavaScript 正为 Promise 添加一个新的方法&#xff0c;使得处理异步函数更加清晰和安全。Promise.try 允许将任何函数包装在 Promise 中&#xff0c;无论它是否异步。使用 Promise.try 可避免传统 try/catch 结构与 Promise 链的混合使用&#xff0c;代码更简洁。try-catc…

MySQL-表的约束(上)

表的约束在 MySQL 中&#xff0c;表的约束&#xff08;Constraints&#xff09;用于确保数据库中数据的完整性和一致性。它们定义了对表中数据的规则和限制&#xff0c;防止无效或不一致的数据被插入、更新或删除。常见的 MySQL 表约束包括主键约束&#xff08;PRIMARY KEY&…

Frida + FART 联手:解锁更强大的 Android 脱壳新姿势

版权归作者所有&#xff0c;如有转发&#xff0c;请注明文章出处&#xff1a;https://cyrus-studio.github.io/blog/ Frida FART 联手能带来什么提升&#xff1f; 增强 FART 的脱壳能力&#xff1a;解决对抗 FART 的壳、动态加载的 dex 的 dump 和修复&#xff1b; 控制 FART…

TLS/SSL(传输层安全协议)

文章目录一、核心概念二、为什么需要 TLS/SSL&#xff1f;三、工作原理与详细流程握手步骤详解&#xff1a;1.ClientHello & ServerHello&#xff1a;2.服务器认证 (Certificate, ServerKeyExchange)&#xff1a;3.客户端响应 (ClientKeyExchange, Finished)&#xff1a;4.…

什么是 AWS 和 GCE ?

AWS 和 GCE 是两种不同厂商提供的云计算服务&#xff0c;主要区别在于提供商和产品定位。AWS全称&#xff1a;Amazon Web Services提供商&#xff1a;亚马逊 (Amazon)简介&#xff1a;全球最大的云计算平台之一&#xff0c;提供完整的云服务&#xff0c;包括&#xff1a; 计算&…

水电站电动机绝缘安全 “不掉线”!在线监测方案筑牢发电保障

对水电站而言&#xff0c;消防水泵、深井水泵等辅助电动机是安全运行的 “关键配角”—— 它们常年处于备用状态&#xff0c;又受潮湿环境影响&#xff0c;绝缘值降低易引发烧毁故障&#xff0c;而传统定期检测难以及时捕捉绝缘劣化趋势&#xff0c;一旦启动时出问题&#xff0…

【Datawhale之Happy-LLM】3种常见的decoder-only模型——Github最火大模型原理与实践教程task07

Task07&#xff1a;第三章 预训练语言模型PLM &#xff08;这是笔者自己的学习记录&#xff0c;仅供参考&#xff0c;原始学习链接&#xff0c;愿 LLM 越来越好❤&#xff09; 本篇介绍3种很典的decoder-only的PLM&#xff08;GPT、LlaMA、GLM&#xff09;。目前火&#x1f52…

【卷积神经网络】卷积神经网络的三大核心优势:稀疏交互、参数共享与等变表示

1. 引言 卷积神经网络(CNN)之所以在计算机视觉、语音识别等领域取得突破性进展,并非偶然。相比传统的全连接神经网络,CNN通过三个重要的思想来帮助改进机器学习系统:稀疏交互(sparse interactions)、参数共享(parameter sharing)、等变表示(equivariant representations)。…