文章的目的為了記錄使用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()
{
}
三、效果演示