文章的目的为了记录使用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.效果演示
一、核心源码分析
- 外观特点
颜色方案:采用黑色背景与亮蓝色(青绿色)的刻度、文字和指针
警告区域:使用橙红色半透明区域标识超速警告
数字显示:底部有数字显示当前值和单位
- 公共接口
这些方法提供了对仪表盘外观和数据的控制。
void setValue(double value); // 设置当前速度值
void setRange(double min, double max); // 设置量程范围
void setUnits(const QString &units); // 设置单位
void setWarningValue(double value); // 设置警告值
- 几何参数
仪表盘覆盖270度的圆弧范围。
double m_startAngle{135}; // 起始角度(135度 - 左下)
double m_endAngle{360+45}; // 结束角度(405度 - 右下)
- 实现文件 (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_OBJECT
public:
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
-
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()
{
}
三、效果演示
