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

程序示例精选

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

如需安装运行环境或远程调试,见文章底部个人QQ名片,由专业技术人员远程协助!

前言

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


文章目录

一、所需工具软件

二、使用步骤

        1. 引入库

        2. 代码实现

        3. 运行结果

三、在线协助

一、所需工具软件

1. VS, Qt

2. C++

二、使用步骤

1.引入库

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

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);
}

3. 运行结果

三、在线协助:

如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助!
1)远程安装运行环境,代码调试
2)Qt, C++, Python入门指导
3)界面美化
4)软件制作

当前文章连接:Python+Qt桌面端与网页端人工客服沟通工具_alicema1111的博客-CSDN博客

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

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

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

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

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

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荷塘月色2

您的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值