Qt+C++自定义控件仪表盘动画仿真

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
大数据开发治理平台 DataWorks,不限时长
简介: 这篇博客针对< Qt+C++自定义控件仪表盘动画仿真>编写代码,代码整洁,规则,易读。 应用推荐首选。

程序示例精选

Python手势识别与追踪

如需安装运行环境或远程调试,可点击右边主头像昵称进入个人主页查看博主联系方式,由专业技术人员远程协助!


前言

这篇博客针对<<Qt+C++自定义控件仪表盘动画仿真>>编写代码,代码整洁,规则,易读。 学习与应用推荐首选。


文章目录

一、所需工具软件

二、使用步骤

       1. 引入库

       2. 代码实现

       3. 运行结果

三、在线协助

一、所需工具软件

1. VS, Qt

2. C++

二、使用步骤

1.引入库

#include <QWidget>
#include <QPropertyAnimation>
#include <QtMath>
#include <QPainter>

image.gif

2. 代码实现

代码如下:

#include "GaugePanel.h"
GaugePanel::~GaugePanel()
{
    hShearAnimation->stop();
    vShearAnimation->stop();
    delete hShearAnimation;
    delete vShearAnimation;
}
void GaugePanel::paintEvent(QPaintEvent*)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);
    //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.translate(width / 2, height / 2);
    painter.scale(side / 215.0, side / 215.0);
    painter.shear(double(hShearValue / 100.0f), double(vShearValue / 100.0f));
    //内层渐变
    drawInnerGradient(&painter);
    //外层渐变
    drawOuterGradient(&painter);
    //外层光晕
    drawOuterHalo(&painter);
    //刻度线
    drawScale(&painter);
    //刻度值
    drawScaleNum(&painter);
    //绘制指针
    drawPointer(&painter);
    //绘制指针扇形
    drawPointerSector(&painter);
    //绘制值
    drawValue(&painter);
    //绘制单位
    drawUnit(&painter);
}
void GaugePanel::drawOuterGradient(QPainter* painter)
{
    if (radiusHalo <= radiusOuter)
        return;
    painter->save();
    QRectF rectangle(0 - radiusHalo, 0 - radiusHalo, radiusHalo * 2, radiusHalo * 2);
    QPen framePen(colorOuterFrame);
    framePen.setWidthF(1.5f);
    painter->setPen(framePen);
    painter->drawEllipse(rectangle);
    painter->setPen(Qt::NoPen);
    QPainterPath smallCircle;
    QPainterPath bigCircle;
    float radius = radiusOuter;
    smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    radius += (radiusHalo - radiusOuter);
    bigCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    //大圆抛去小圆部分
    QPainterPath gradientPath = bigCircle - smallCircle;
    QRadialGradient gradient(0, 0, radius, 0, 0);
    //gradient.setSpread(QGradient::ReflectSpread);
    gradient.setColorAt(0.85, colorOuterStart);
    gradient.setColorAt(0.98, colorOuterEnd);
    painter->setBrush(gradient);
    painter->drawPath(gradientPath);
    painter->restore();
}
void GaugePanel::drawInnerGradient(QPainter* painter)
{
    if (radiusOuter <= radiusInner)
        return;
    painter->save();
    painter->setPen(Qt::NoPen);
    QPainterPath smallCircle;
    QPainterPath bigCircle;
    float radius = radiusInner;
    smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    radius += (radiusOuter - radiusInner);
    bigCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    //大圆抛去小圆部分
    QPainterPath gradientPath = bigCircle - smallCircle;
    QRadialGradient gradient(0, 0, radius, 0, 0);
    //gradient.setSpread(QGradient::ReflectSpread);
    gradient.setColorAt(0.7, colorInnerStart);
    gradient.setColorAt(1, colorInnerEnd);
    painter->setBrush(gradient);
    painter->drawPath(gradientPath);
    painter->restore();
}
void GaugePanel::drawOuterHalo(QPainter* painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);
    QPainterPath smallCircle;
    QPainterPath bigCircle;
    float radius = radiusHalo;
    smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    radius += (110.0 - radiusHalo);
    bigCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    //大圆抛去小圆部分
    QPainterPath gradientPath = bigCircle - smallCircle;
    QRadialGradient gradient(0, 0, 100, 0, 0);
    gradient.setSpread(QGradient::ReflectSpread);
    gradient.setColorAt(radiusHalo / 100, colorHaloStart);
    gradient.setColorAt(1, colorHaloEnd);
    painter->setBrush(gradient);
    painter->drawPath(gradientPath);
    painter->restore();
}
void GaugePanel::drawScale(QPainter* painter)
{
    float radius = 85;
    painter->save();
    painter->setPen(QColor(255, 255, 255));
    painter->rotate(30);
    int steps = (30);
    double angleStep = (360.0 - 60) / steps;
    QPen pen = painter->pen();
    pen.setCapStyle(Qt::RoundCap);
    for (int i = 0; i <= steps; i++) {
        if (i % 3 == 0) {
            pen.setWidthF(1.5);
            painter->setPen(pen);
            QLineF line(0.0f, radius - 8.0f, 0.0f, radius);
            painter->drawLine(line);
        }
        else {
            pen.setWidthF(0.5);
            painter->setPen(pen);
            QLineF line(0.0f, radius - 3.0f, 0.0f, radius);
            painter->drawLine(line);
        }
        painter->rotate(angleStep);
    }
    painter->restore();
}
void GaugePanel::drawScaleNum(QPainter* painter)
{
    float radius = 95.0f;
    painter->save();
    painter->setPen(QColor(255, 255, 255));
    double startRad = (330 - 90) * (M_PI / 180);
    double deltaRad = (300) * (M_PI / 180) / 10;
    for (int i = 0; i <= 10; i++) {
        double sina = sin(startRad - i * deltaRad);
        double cosa = cos(startRad - i * deltaRad);
        double value = 1.0 * i * ((30) / 10);//刻度值范围
        QString strValue = QString("%1").arg((double)value, 0, 'f', 0);
        double textWidth = fontMetrics().width(strValue);
        double textHeight = fontMetrics().height();
        int x = radius * cosa - textWidth / 2;
        int y = -radius * sina + textHeight / 4;
        painter->drawText(x, y, strValue);
    }
    painter->restore();
}
void GaugePanel::drawPointer(QPainter* painter)
{
    painter->save();
    float radius = 83.0;
    painter->rotate(30 + int(value * 10));
    QPen pen = painter->pen();
    pen.setWidthF(1.0);
    pen.setColor(QColor(50, 154, 255, 200));
    painter->setPen(pen);
    QLineF line(0.0f, 0.0f, 0.0f, radius);
    painter->drawLine(line);
    painter->restore();
}
void GaugePanel::drawPointerSector(QPainter* painter)
{
    float radius = 87.5f;
    painter->save();
    painter->setPen(Qt::NoPen);
    QRectF rect(-radius, -radius, radius * 2, radius * 2);
    painter->setBrush(QColor(50, 154, 255, 50));
    painter->drawPie(rect, -120 * 16, -value * 16 * 10);
    painter->restore();
}
void GaugePanel::drawValue(QPainter* painter)
{
    int radius = 100;
    painter->save();
    painter->setPen(QColor(255, 255, 255));
    painter->setFont(QFont("Arial", 22, 22, true));
    QRectF textRect(-radius, -radius, radius * 2, radius * 2);
    QString strValue = QString("%1").arg((double)value, 0, 'f', 0);
    painter->drawText(textRect, Qt::AlignCenter, strValue);
    painter->restore();
}
void GaugePanel::drawUnit(QPainter* painter)
{
    int radius = 100;
    painter->save();
    painter->setPen(QColor(255, 255, 255));
    painter->setFont(QFont("Arial", 9, -1, true));
    QRectF textRect(-radius, -radius + 20, radius * 2, radius * 2);
    painter->drawText(textRect, Qt::AlignCenter, "km/h");
    painter->restore();
}
double GaugePanel::getValue() const
{
    return this->value;
}
int GaugePanel::getHShearValue() const
{
    return this->hShearValue;
}
int GaugePanel::getVShearValue() const
{
    return this->vShearValue;
}
double GaugePanel::getRadiusInner() const
{
    return radiusInner;
}
double GaugePanel::getRadiusOuter() const
{
    return radiusOuter;
}
double GaugePanel::getRadiusHalo() const
{
    return radiusHalo;
}
QColor GaugePanel::getColorOuterFrame() const
{
    return colorOuterFrame;
}
QColor GaugePanel::getColorInnerStart() const
{
    return colorInnerStart;
}
QColor GaugePanel::getColorInnerEnd() const
{
    return colorInnerEnd;
}
QColor GaugePanel::getColorOuterStart() const
{
    return colorOuterStart;
}
QColor GaugePanel::getColorOuterEnd() const
{
    return colorOuterEnd;
}
QColor GaugePanel::getColorHaloStart() const
{
    return colorHaloStart;
}
QColor GaugePanel::getColorHaloEnd() const
{
    return colorHaloEnd;
}
void GaugePanel::setValue(int value)
{
    setValue(double(value));
}
void GaugePanel::setValue(double value) {
    updateValue(value);
}
void GaugePanel::setHShearValue(int value)
{
    if (value > 100 || value < -100)
        return;
    this->hShearValue = value;
    update();
}
void GaugePanel::setVShearValue(int value)
{
    if (value > 100 || value < -100)
        return;
    this->vShearValue = value;
    update();
}
void GaugePanel::setColorOuterFrame(QColor color)
{
    colorOuterFrame = color;
}
void GaugePanel::setRadiusInner(int radius)
{
    setRadiusInner(double(radius));
}
void GaugePanel::setRadiusInner(double radius)
{
    if (radius >= 0.0f && radius < 100.0f) {
        radiusInner = radius;
        update();
    }
}
void GaugePanel::setRadiusOuter(int radius)
{
    setRadiusOuter(double(radius));
}
void GaugePanel::setRadiusOuter(double radius)
{
    if (radius > 0.0f && radius < 100.0f) {
        radiusOuter = radius;
        update();
    }
}
void GaugePanel::setRadiusHalo(int radius)
{
    setRadiusHalo(double(radius));
}
void GaugePanel::setRadiusHalo(double radius)
{
    if (radius > 0.0f && radius < 100.0f) {
        radiusHalo = radius;
        update();
    }
}
void GaugePanel::setColorInnerStart(QColor color)
{
    colorInnerStart = color;
}
void GaugePanel::setColorInnerEnd(QColor color)
{
    colorInnerEnd = color;
}
void GaugePanel::setColorOuterStart(QColor color)
{
    colorOuterStart = color;
}
void GaugePanel::setColorOuterEnd(QColor color)
{
    colorOuterEnd = color;
}
void GaugePanel::setColorHaloStart(QColor color)
{
    colorHaloStart = color;
}
void GaugePanel::setColorHaloEnd(QColor color)
{
    colorHaloEnd = color;
}
void GaugePanel::startShearAnimal(int duration, int hShearValue, int vShearValue)
{
    if (hShearValue == this->hShearValue && vShearValue == this->vShearValue) {
        return;
    }
    if (hShearAnimation->state() != QPropertyAnimation::Stopped) {
        hShearAnimation->stop();
    }
    if (vShearAnimation->state() != QPropertyAnimation::Stopped) {
        vShearAnimation->stop();
    }
    hShearAnimation->setDuration(duration);
    hShearAnimation->setStartValue(this->hShearValue);
    hShearAnimation->setEndValue(hShearValue);
    hShearAnimation->start();
    vShearAnimation->setDuration(duration);
    vShearAnimation->setStartValue(this->vShearValue);
    vShearAnimation->setEndValue(vShearValue);
    vShearAnimation->start();
}
void GaugePanel::updateValue(double value)
{
    if (value > 30.0 || value < 0.0) {
        return;
    }
    this->value = value;
    //update();
    this->update();
    // emit valueChanged(value);
}

image.gif

3. 运行结果

image.gif编辑

image.gif编辑

三、在线协助:

如需安装运行环境或远程调试, 可点击右边 主头像 昵称 进入个人主页查看博主联系方式 ,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Qt, C++, Python入门指导
3)界面美化
4)软件制作


博主推荐文章:python人脸识别统计人数qt窗体-CSDN博客

博主推荐文章:Python Yolov5火焰烟雾识别源码分享-CSDN博客

                        Python OpenCV识别行人入口进出人数统计_python识别人数-CSDN博客

个人博客主页:alicema1111的博客_CSDN博客-Python,C++,网页领域博主

博主所有文章点这里:alicema1111的博客_CSDN博客-Python,C++,网页领域博主


相关文章
|
22天前
|
安全 网络协议 数据安全/隐私保护
掌握Qt和C++:构建你的第一个P2P应用程序
掌握Qt和C++:构建你的第一个P2P应用程序
133 3
|
22天前
|
编译器 API C语言
深入探究Qt与C++标准的兼容之旅
深入探究Qt与C++标准的兼容之旅
130 3
|
22天前
|
存储 算法 API
【Qt 基本类】QDateTime类在C++中的应用与深度解析
【Qt 基本类】QDateTime类在C++中的应用与深度解析
57 0
|
22天前
|
安全 前端开发 C++
C++视角下的Qt按钮:从基础应用到高级定制(二)
C++视角下的Qt按钮:从基础应用到高级定制
53 2
|
22天前
|
XML JSON 算法
C++视角下的Qt按钮:从基础应用到高级定制(一)
C++视角下的Qt按钮:从基础应用到高级定制
139 2
|
22天前
|
XML 安全 C++
DBus类型系统以及在Qt和C++ 中的使用(二)
DBus类型系统以及在Qt和C++ 中的使用
73 0
|
22天前
|
XML 存储 Unix
DBus类型系统以及在Qt和C++ 中的使用(一)
DBus类型系统以及在Qt和C++ 中的使用
112 0
|
22天前
|
存储 开发框架 开发者
QT C++焦点事件:多角度解析实用技巧与方法
QT C++焦点事件:多角度解析实用技巧与方法
339 0
|
22天前
|
网络协议 C++
C++ Qt开发:QTcpSocket网络通信组件
`QTcpSocket`和`QTcpServer`是Qt中用于实现基于TCP(Transmission Control Protocol)通信的两个关键类。TCP是一种面向连接的协议,它提供可靠的、双向的、面向字节流的通信。这两个类允许Qt应用程序在网络上建立客户端和服务器之间的连接。Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍如何运用`QTcpSocket`组件实现基于TCP的网络通信功能。
53 8
C++ Qt开发:QTcpSocket网络通信组件
|
22天前
|
编译器 API 数据安全/隐私保护
深入对比:Qt 的 QFile/QFileInfo 和与 C++17 Filesystem 和标准文件流 的细节剖析
深入对比:Qt 的 QFile/QFileInfo 和与 C++17 Filesystem 和标准文件流 的细节剖析
128 3