Qt自定义控件:汽车速度表

news/2024/11/9 4:43:46/
1、功能

制作一个汽车速度表

2、实现

从外到内进行绘制,初始化画布,画渐变色外圈,画刻度,写刻度文字,画指针,画扇形,画内圈渐变色,画黑色内圈,写当前值

3、效果

汽车速度表

4、源码
a、头文件
#ifndef CARDASHBOARD_H
#define CARDASHBOARD_H#include <QTimer>
#include <QWidget>class CarDashboard : public QWidget {Q_OBJECTpublic:CarDashboard(QWidget *parent = nullptr);~CarDashboard();protected:void paintEvent(QPaintEvent *event);private:void startSpeed();void initCanvas(QPainter &painter);void drawOutterShine(QPainter &painter);void drawScale(QPainter &painter);void drawScaleText(QPainter &painter);void drawPointer(QPainter &painter);void drawSector(QPainter &painter);void drawInnerShine(QPainter &painter);void drawInnerBlack(QPainter &painter);void drawCurrentValue(QPainter &painter);private:const int kScaleAngle = 240;   // 刻度扇形角度const int kScaleNum = 60;      // 刻度数量const int kLengthScale = 5;    // 长刻度与刻度比例const int kOneScaleValue = 4;  // 一个刻度对应值double av_angle_ = 0;               // 平均角度int start_rotate_angle_clock_ = 0;  // 起始旋转角度(顺时针)(推算出来的)int start_rotate_angle_ = 0;  // 起始旋转角度(逆时针)(推算出来的)int pointer_dir_ = 0;        // 指针旋转方向int scale_value_ = 0;        // 刻度值int height_half_ = 0;        // 高度一半int min_unit_ = 0;           // 最小单位值int font_size_ = 0;          // 字体大小int scale_text_radius_ = 0;  // 刻度文字半径int indent_value_ = 0;       // 刻度缩进值QTimer *timer_ = nullptr;  // 定时器
};
#endif  // CARDASHBOARD_H
b、源文件
#include "cardashboard.h"#include <QPainter>
#include <QtMath>CarDashboard::CarDashboard(QWidget *parent) : QWidget(parent) {av_angle_ = kScaleAngle * 1.0 / kScaleNum;start_rotate_angle_clock_ = -kScaleAngle / 2 + 270;start_rotate_angle_ = kScaleAngle / 2 + 90;startSpeed();
}CarDashboard::~CarDashboard() {}void CarDashboard::startSpeed() {timer_ = new QTimer(this);connect(timer_, &QTimer::timeout, [=]() {update();if (pointer_dir_ == 0) {scale_value_++;if (scale_value_ >= kScaleNum) {pointer_dir_ = 1;}} else if (pointer_dir_ == 1) {scale_value_--;if (scale_value_ == 0) {pointer_dir_ = 0;}}});timer_->setInterval(50);timer_->start();
}void CarDashboard::initCanvas(QPainter &painter) {painter.setRenderHint(QPainter::Antialiasing, true);// 黑色背景painter.setBrush(Qt::black);painter.drawRect(rect());painter.setBrush(Qt::NoBrush);painter.translate(QPoint(width() / 2, height() * 0.6));height_half_ = height() / 2;                            // 高度一半min_unit_ = height() / 16;                              //  最小单位值font_size_ = min_unit_ * 2 / 5;                         // 字体大小scale_text_radius_ = height_half_ - min_unit_ * 7 / 8;  // 刻度文字半径indent_value_ = min_unit_ / 8;                          // 刻度缩进大
}void CarDashboard::drawOutterShine(QPainter &painter) {const int radius = height_half_ + min_unit_ / 2;painter.save();QRect rect(-radius, -radius, radius * 2, radius * 2);QRadialGradient gradient(0, 0, radius);gradient.setColorAt(1.0, QColor(255, 0, 0, 200));gradient.setColorAt(0.97, QColor(255, 0, 0, 120));gradient.setColorAt(0.92, QColor(0, 0, 0, 0));gradient.setColorAt(0.0, QColor(0, 0, 0, 0));painter.setPen(Qt::NoPen);painter.setBrush(gradient);painter.drawPie(rect, start_rotate_angle_ * 16, -av_angle_ * kScaleNum * 16);painter.restore();
}void CarDashboard::drawScale(QPainter &painter) {painter.save();painter.setPen(QPen(Qt::white, 3));painter.rotate(start_rotate_angle_clock_);for (int i = 0; i <= kScaleNum; i++) {if (i >= 40) {painter.setPen(QPen(Qt::red, 3));}if (i % kLengthScale == 0) {  // 长刻度painter.drawLine(height_half_ - min_unit_ / 2, 0,height_half_ - indent_value_, 0);} else {  // 短刻度painter.drawLine(height_half_ - min_unit_ / 4, 0,height_half_ - indent_value_, 0);}painter.rotate(av_angle_);}painter.restore();
}// 这个函数是难点
void CarDashboard::drawScaleText(QPainter &painter) {painter.save();painter.setPen(QPen(Qt::white, 3));QFont font("Arial", font_size_);font.setBold(true);painter.setFont(font);for (int i = 0; i <= kScaleNum; i++) {if (i % kLengthScale == 0) {// 保存坐标painter.save();// 正弦 余弦int del_x = qCos(qDegreesToRadians(start_rotate_angle_ - av_angle_ * i)) *scale_text_radius_;int del_y = qSin(qDegreesToRadians(start_rotate_angle_ - av_angle_ * i)) *scale_text_radius_;// 平移坐标系painter.translate(QPoint(del_x, -del_y));// 选择坐标系painter.rotate(-kScaleAngle / 2 + av_angle_ * i);// 绘制文字painter.drawText(QRect(-min_unit_ / 2, -min_unit_ / 2, min_unit_, min_unit_),Qt::AlignCenter, QString::number(i * kOneScaleValue));// 恢复坐标painter.restore();}}painter.restore();
}void CarDashboard::drawPointer(QPainter &painter) {painter.save();painter.setPen(Qt::NoPen);painter.setBrush(Qt::white);const QPointF point[4]{QPointF(0, 0.0),QPointF(height_half_ - min_unit_ * 5 / 2, -min_unit_ / 32.0),QPointF(height_half_ - min_unit_ * 5 / 2, min_unit_ / 32.0),QPointF(0, min_unit_ / 3.0),};painter.rotate(start_rotate_angle_clock_ + av_angle_ * scale_value_);painter.drawPolygon(point, 4);painter.restore();
}void CarDashboard::drawSector(QPainter &painter) {const int radius = height_half_ + min_unit_ / 2;painter.save();painter.setPen(Qt::NoPen);painter.setBrush(QColor(255, 0, 0, 50));QRect rect(-radius, -radius, radius * 2, radius * 2);painter.drawPie(rect, start_rotate_angle_ * 16,-av_angle_ * scale_value_ * 16);painter.restore();
}void CarDashboard::drawInnerShine(QPainter &painter) {painter.setBrush(QColor(255, 0, 0, 150));painter.drawEllipse(QPoint(0, 0), min_unit_ * 2, min_unit_ * 2);
}void CarDashboard::drawInnerBlack(QPainter &painter) {painter.setBrush(Qt::black);painter.drawEllipse(QPoint(0, 0), min_unit_ * 3 / 2, min_unit_ * 3 / 2);
}void CarDashboard::drawCurrentValue(QPainter &painter) {painter.setPen(QPen(Qt::white, 3));QFont font("Arial", font_size_ * 3 / 2);font.setBold(true);painter.setFont(font);painter.drawText(QRect(-min_unit_, -min_unit_, min_unit_ * 2, min_unit_),Qt::AlignCenter,QString::number(scale_value_ * kOneScaleValue));font.setPointSize(font_size_ * 3 / 4);painter.setFont(font);painter.drawText(QRect(-min_unit_, min_unit_ / 2, min_unit_ * 2, min_unit_ / 2),Qt::AlignCenter, "Km/h");
}void CarDashboard::paintEvent(QPaintEvent *event) {Q_UNUSED(event);QPainter painter(this);// 初始化画布initCanvas(painter);// 画外圈渐变色drawOutterShine(painter);// 画刻度drawScale(painter);// 写刻度文字drawScaleText(painter);// 画指针drawPointer(painter);// 画扇形drawSector(painter);// 画内圈渐变色drawInnerShine(painter);// 画黑色内圈drawInnerBlack(painter);// 当前值drawCurrentValue(painter);
}
5、难点

这里难点使用正弦和余弦计算绘制刻度字。

对你有用就点个赞👍,以后需要用到就收藏⭐


http://www.ppmy.cn/news/1545530.html

相关文章

练习LabVIEW第四十四题

学习目标&#xff1a; 计算学生三门课(语文&#xff0c;数学&#xff0c;英语)的平均分&#xff0c;并根据平均分划分成绩等级。要求输出等级A,B,C,D,E。90分以上为A&#xff0c;80&#xff5e;89为B&#xff0c;70&#xff5e;79为C&#xff0c;60&#xff5e;69为D&#xff…

mac电脑如何远程登录自己购买的阿里云服务器

密码登录 示例 ssh root125.12.45.32 # 其中root是用户名&#xff0c;125.12.45.32是阿里云服务器的公网ipjava0904weigongdeMBP ~ % ssh root106.15.186.127 The authenticity of host 106.15.186.127 (106.15.186.127) cant be established. ED25519 key fingerprint is SH…

Redis Pipeline技术

Redis作为高性能的键值存储系统&#xff0c;广泛应用于缓存、会话存储、消息队列等多种场景。随着应用程序对性能和吞吐量的要求不断提高&#xff0c;传统的Redis命令执行方式可能会成为瓶颈。为了解决这个问题&#xff0c;Redis引入了Pipeline技术&#xff0c;通过批量执行命令…

Pod安装软件将CDN改为国内的镜像

1、碰到错误 在pod install的时候碰到以下的下载错误&#xff1a; 文字错误如下&#xff1a; CDN: trunk URL couldnt be downloaded: https://cdn.jsdelivr.net/cocoa/Specs/5/b/d/OpenCV/2.4.11/OpenCV.podspec.json Response: Timeout was reached CDN: trunk URL couldn…

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置...-CSDN博客 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明-CSDN博客 工作…

Spring Boot 项目启动时打印端口号、项目名及访问地址

背景 在开发过程中&#xff0c;我们经常需要在项目启动时知道应用使用的端口号和访问地址。为了提高开发效率&#xff0c;我们可以通过简单的配置&#xff0c;在项目启动后直接把这些信息打印在控制台上。 解决方案 通过使用 Environment 类&#xff0c;可以在项目启动时获取…

Python学习从0到1 day26 第三阶段 Spark ①

要学会 剥落旧痂 然后 循此新生 —— 24.11.8 一、Spark是什么 定义&#xff1a; Apache Spark 是用于大规模数据处理的统一分析引擎 简单来说&#xff0c;Spark是一款分布式的计算框架&#xff0c;用于调度成百上千的服务器集群&#xff0c;计算TB、PB乃至EB级别的海量数据…

使用CentOS宝塔面板docker搭建EasyTier内网穿透服务

0. 前言 EasyTier是一个简单、安全、去中心化的内网穿透 VPN 组网方案&#xff0c;部署方便&#xff0c;支持 MacOS/Linux/Windows/FreeBSD/Android平台&#xff0c;而且作者搭建了一个公共服务器&#xff0c;不想折腾自建服务&#xff0c;可以使用默认的公共服务器地址 tcp:/…