開源 C++ QT Widget 開發(九)圖表--儀表盤

文章的目的為了記錄使用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)。…