Qt自定义精美的仪表盘控件(汽车仪表、指南针、雷达、摇杆)

一、网速测速仪表盘

在这里插入图片描述

#include "Frm_GaugeSpeed.h"
#include <QTimer>
#include <QPainter>
#include <QtMath>
#include <QDebug>

//QString qss1 = QString("QLabel{background-color:rgb(0,0,0);color:rgb(%1);}").arg("100,184,255");
//QString qss2 = QString("QLabel{background-color:rgb(0,0,0);color:rgb(%1);}").arg("255,107,107");
//QString qss3 = QString("QLabel{background-color:rgb(0,0,0);color:rgb(%1);}").arg("24,189,155");


//===================================================================================
// 函数名称 | Frm_GaugeSpeed()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |构造函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_GaugeSpeed::Frm_GaugeSpeed(QWidget *parent) : QWidget(parent)
{
    m_timer = new QTimer(this);
    m_timer->setInterval(1000);
    m_timer->start();
    connect(m_timer, SIGNAL(timeout()), this, SLOT(slotAnimaValue()));

    if(this->m_isAnimation == true)
    {
        QTimer::singleShot(50, this, SLOT(slotUpdateValue()));
    }

}
//===================================================================================
// 函数名称 | ~Frm_GaugeSpeed()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |析构函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_GaugeSpeed::~Frm_GaugeSpeed()
{

}


//===================================================================================
// 函数名称 | drawScale()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 | 绘制刻度线
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_GaugeSpeed::drawScale(QPainter *painter)
{
    int radius = 94;
    painter->save();

    QPen pen;
    pen.setCapStyle(Qt::RoundCap);

    painter->rotate(m_IntSartAngle);
    int steps = (m_IntScaleMajor * m_IntScaleMinor);
    double angleStep = (360.0 - m_IntSartAngle - m_IntEndAngle) / steps;

    //计算圆环对应大刻度范围索引
    int indexStart = steps * (double)m_IntRingStartPercent / 100 + 1;
    int indexMid = steps * (double)m_IntRingMidPercent / 100 - 1;
    int indexEnd = steps * (double)m_IntRingEndPercent / 100 + 1;
    int index = 0;

    for (int i = 0; i <= steps; i++)
    {
        if (i % m_IntScaleMinor == 0)
        {
            //根据所在圆环范围切换颜色
            if (index < indexStart) {
                pen.setColor(m_ColorRingStart);
            } else if (index < (indexStart + indexMid)) {
                pen.setColor(m_ColorRingMid);
            } else if (index < (indexStart + indexMid + indexEnd)) {
                pen.setColor(m_ColorRingEnd);
            }

            index++;

            pen.setWidthF(1.5);
            painter->setPen(pen);
            painter->drawLine(0, radius - 13, 0, radius);
        } else {
            pen.setWidthF(0.5);
            pen.setColor(QColor(0,255,255));
            painter->setPen(pen);
            painter->drawLine(0, radius - 5, 0, radius);
        }

        painter->rotate(angleStep);
    }

    painter->restore();
}


//===================================================================================
// 函数名称 | drawPointer()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 | 绘制指针
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_GaugeSpeed::drawPointer(QPainter *painter)
{
    int radius = 62;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(m_pointerColor);

    QPolygon pts;
    pts.setPoints(4, -5, 0, 0, -8, 5, 0, 0, radius);

    painter->rotate(m_IntSartAngle);
    double degRotate = (360.0 - m_IntSartAngle - m_IntEndAngle) / (m_dMaxValue - m_dMinValue) * (m_dCurrentValue - m_dMinValue);
    painter->rotate(degRotate);
    painter->drawConvexPolygon(pts);

    painter->restore();
}




double Frm_GaugeSpeed::getMinValue() const
{
    return this->m_dMinValue;
}

double Frm_GaugeSpeed::getMaxValue() const
{
    return this->m_dMaxValue;
}

double Frm_GaugeSpeed::getValue() const
{
    return this->m_dCurrentValue;
}

int Frm_GaugeSpeed::getPrecision() const
{
    return this->m_IntPreciBit;
}

int Frm_GaugeSpeed::getScaleMajor() const
{
    return this->m_IntScaleMajor;
}

int Frm_GaugeSpeed::getScaleMinor() const
{
    return this->m_IntScaleMinor;

}

int Frm_GaugeSpeed::getStartAngle() const
{
    return this->m_IntSartAngle;
}

int Frm_GaugeSpeed::getEndAngle() const
{
    return this->m_IntEndAngle;
}

bool Frm_GaugeSpeed::getAnimation() const
{
    return this->m_isAnimation;
}

double Frm_GaugeSpeed::getAnimationStep() const
{
    return this->m_dAnimationStep;
}

int Frm_GaugeSpeed::getRingWidth() const
{
    return  this->m_IntRingWidth;
}

int Frm_GaugeSpeed::getRingStartPercent() const
{
    return this->m_IntRingStartPercent;
}

int Frm_GaugeSpeed::getRingMidPercent() const
{
    return this->m_IntRingMidPercent;
}

int Frm_GaugeSpeed::getRingEndPercent() const
{
    return  this->m_IntRingEndPercent;
}

QColor Frm_GaugeSpeed::getRingColorStart() const
{
    return this->m_ColorRingStart;
}

QColor Frm_GaugeSpeed::getRingColorMid() const
{
    return this->m_ColorRingMid;
}

QColor Frm_GaugeSpeed::getRingColorEnd() const
{
    return this->m_ColorRingEnd;
}

QColor Frm_GaugeSpeed::getPointerColor() const
{
    return this->m_pointerColor;
}

QColor Frm_GaugeSpeed::getTextColor() const
{
    return this->m_textColor;
}

QSize Frm_GaugeSpeed::sizeHint() const
{
    int width = this->width();
    int height = this->height();
    return QSize(qMin(width, height), qMin(width, height));
}

QSize Frm_GaugeSpeed::minimumSizeHint() const
{
    int width = this->width();
    int height = this->height();
    return QSize(qMin(width, height), qMin(width, height));
}



void Frm_GaugeSpeed::setRange(double minValue, double maxValue)
{
    this->m_dMinValue = minValue;
    this->m_dMaxValue = maxValue;

}

void Frm_GaugeSpeed::setRange(int minValue, int maxValue)
{
    this->m_dMinValue = minValue;
    this->m_dMaxValue = maxValue;

}


void Frm_GaugeSpeed::setValue(double value)
{
    this->m_dTargetValue = value;
    if(this->m_isAnimation == true)
    {
        QTimer::singleShot(5, this, SLOT(slotUpdateValue()));
    }
    else {
        this->m_dCurrentValue = this->m_dTargetValue;
    }
    update();

}

void Frm_GaugeSpeed::setValue(int value)
{
    this->m_dTargetValue =value;
    if(this->m_isAnimation == true)
    {
        QTimer::singleShot(5, this, SLOT(slotUpdateValue()));
    }
    else {
        this->m_dCurrentValue = this->m_dTargetValue;
    }
    update();
}

void Frm_GaugeSpeed::setValue(QString &value)
{
    this->m_dTargetValue = value.toDouble();
    if(this->m_isAnimation == true)
    {
        QTimer::singleShot(5, this, SLOT(slotUpdateValue()));
    }
    else {
        this->m_dCurrentValue = this->m_dTargetValue;
    }
    update();
}


void Frm_GaugeSpeed::setAnimation(bool animation)
{
    this->m_isAnimation = animation;
    if(this->m_isAnimation == true)
    {
        QTimer::singleShot(5, this, SLOT(slotUpdateValue()));
    }

}




void Frm_GaugeSpeed::slotUpdateValue()
{
    if(this->m_isAnimation == true)
    {
        if(fabs(m_dCurrentValue - m_dTargetValue) > 0.001)
        {
            if(m_dCurrentValue - m_dTargetValue > 0.001)
                m_dCurrentValue = m_dCurrentValue - m_dAnimationStep;
            else {
                m_dCurrentValue = m_dCurrentValue + m_dAnimationStep;
            }
            QTimer::singleShot(5, this, SLOT(slotUpdateValue()));
            update();
        }
    }

}



//===================================================================================
// 函数名称 | slotAnimaValue()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 | 模拟计数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_GaugeSpeed::slotAnimaValue()
{
    setValue(m_dCurrentValue+m_dAnimationStep);

}

二、汽车仪表盘

在这里插入图片描述

#include "Frm_Dashboard.h"
#include <QTimer>
#include <QPainter>
#include <QtMath>
#include <QDebug>



//===================================================================================
// 函数名称 | Frm_Dashboard()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |构造函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_Dashboard::Frm_Dashboard(QWidget *parent) : QWidget(parent)
{
    m_timer = new QTimer(this);
    m_timer->setInterval(1000);
    m_timer->start();
    connect(m_timer, SIGNAL(timeout()), this, SLOT(slotAnimaValue()));

    if(this->m_isAnimation == true)
    {
        QTimer::singleShot(50, this, SLOT(slotUpdateValue()));
    }

}
//===================================================================================
// 函数名称 | ~Frm_Dashboard()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |析构函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_Dashboard::~Frm_Dashboard()
{

}

double Frm_Dashboard::getMinValue() const
{
    return this->m_dMinValue;
}

double Frm_Dashboard::getMaxValue() const
{
    return this->m_dMaxValue;
}

double Frm_Dashboard::getValue() const
{
    return this->m_dCurrentValue;
}

int Frm_Dashboard::getPrecision() const
{
    return this->m_IntPreciBit;
}

int Frm_Dashboard::getScaleMajor() const
{
    return this->m_IntScaleMajor;
}

int Frm_Dashboard::getScaleMinor() const
{
    return this->m_IntScaleMinor;

}

int Frm_Dashboard::getStartAngle() const
{
    return this->m_IntSartAngle;
}

int Frm_Dashboard::getEndAngle() const
{
    return this->m_IntEndAngle;
}

bool Frm_Dashboard::getAnimation() const
{
    return this->m_isAnimation;
}

double Frm_Dashboard::getAnimationStep() const
{
    return this->m_dAnimationStep;
}


QColor Frm_Dashboard::getPointerColor() const
{
    return this->m_pointerColor;
}

QColor Frm_Dashboard::getTextColor() const
{
    return this->m_textColor;
}

QSize Frm_Dashboard::sizeHint() const
{
    int width = this->width();
    int height = this->height();
    return QSize(qMin(width, height), qMin(width, height));
}

QSize Frm_Dashboard::minimumSizeHint() const
{
    int width = this->width();
    int height = this->height();
    return QSize(qMin(width, height), qMin(width, height));
}


//===================================================================================
// 函数名称 | paintEvent()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 |绘制事件
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Dashboard::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 / 200.0, side / 200.0); /* 比例缩放 */

    drawRing(&painter);
    drawScale(&painter);
    drawScaleNum(&painter);
    drawOverlay(&painter);
    drawPointer(&painter);
    drawValue(&painter);
}
//===================================================================================
// 函数名称 | drawRing()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 | 绘制外围环
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Dashboard::drawRing(QPainter *painter)
{
    int r = m_Radius;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(QColor(172, 172, 172));//外围
    painter->drawEllipse(-r, -r, r * 2, r * 2);

    r =  m_Radius * 0.9;
    painter->setBrush(QColor(0, 26, 51));//内圆
    painter->setPen(Qt::NoPen);
    painter->drawEllipse(-r, -r, r * 2, r * 2);
    painter->restore();
}

三、指南针表盘

在这里插入图片描述

#include "Frm_Compass.h"
#include <QTimer>
#include <QPainter>
#include <QtMath>
#include <QDebug>



//===================================================================================
// 函数名称 | Frm_Compass()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |构造函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_Compass::Frm_Compass(QWidget *parent) : QWidget(parent)
{
    m_timer = new QTimer(this);
    m_timer->setInterval(1000);
    m_timer->start();
    connect(m_timer, SIGNAL(timeout()), this, SLOT(slotAnimaValue()));

    if(this->m_isAnimation == true)
    {
        QTimer::singleShot(50, this, SLOT(slotUpdateValue()));
    }

}
//===================================================================================
// 函数名称 | ~Frm_Compass()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |析构函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_Compass::~Frm_Compass()
{

}

double Frm_Compass::getValue() const
{
    return this->m_dCurrentValue;
}

int Frm_Compass::getPrecision() const
{
    return this->m_IntPreciBit;
}


bool Frm_Compass::getAnimation() const
{
    return this->m_isAnimation;
}

double Frm_Compass::getAnimationStep() const
{
    return this->m_dAnimationStep;
}


QColor Frm_Compass::getTextColor() const
{
    return this->m_textColor;
}

QSize Frm_Compass::sizeHint() const
{
    int width = this->width();
    int height = this->height();
    return QSize(qMin(width, height), qMin(width, height));
}

QSize Frm_Compass::minimumSizeHint() const
{
    int width = this->width();
    int height = this->height();
    return QSize(qMin(width, height), qMin(width, height));
}


//===================================================================================
// 函数名称 | paintEvent()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 |绘制事件
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Compass::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 / 200.0, side / 200.0);


    //绘制外边框圆
    drawRing(&painter);
    //绘制背景圆
    drawBgCircle(&painter);
    //绘制刻度
    drawScale(&painter);
    //绘制东南西北标识
    drawScaleNum(&painter);
    //绘制覆盖圆外圆
    drawCoverOuterCircle(&painter);
    //绘制覆盖圆内圆
    drawCoverInnerCircle(&painter);
    //绘制覆盖圆中心圆
    drawCoverCenterCircle(&painter);
    //绘制南北指针
    drawPointer(&painter);
    //绘制中心圆
    drawCenterCircle(&painter);
    //绘制当前值
    drawValue(&painter);
    //绘制遮罩
    drawOverlay(&painter);
}

//==================================================================================================
//| 函数名称 | drawOverlay()
//|-------------------------------------------------------------------------------------------------
//| 函数功能 | 绘制遮罩层
//|-------------------------------------------------------------------------------------------------
//| 输入参数 |painter画家
//|-------------------------------------------------------------------------------------------------
//| 返回参数 |
//|-------------------------------------------------------------------------------------------------
//| 函数设计 | xt,2020.10.16
//==================================================================================================
void Frm_Compass::drawOverlay(QPainter *painter)
{
    int radius = 100;
    painter->save();
    painter->setPen(Qt::NoPen);

    QPainterPath smallCircle;
    QPainterPath bigCircle;
    radius -= 1;
    smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    radius *= 2;
    bigCircle.addEllipse(-radius, -radius + 140, radius * 2, radius * 2);

    //高光的形状为小圆扣掉大圆的部分
    QPainterPath highlight = smallCircle - bigCircle;

    QLinearGradient linearGradient(0, -radius / 2, 0, 0);
    m_overlayColor.setAlpha(100);
    linearGradient.setColorAt(0.0, m_overlayColor);
    m_overlayColor.setAlpha(30);
    linearGradient.setColorAt(1.0, m_overlayColor);
    painter->setBrush(linearGradient);
    painter->rotate(-20);
    painter->drawPath(highlight);

    painter->restore();
}

四、钢铁侠雷达扫描

在这里插入图片描述

#include "Frm_Radar.h"

#include <QPainter>
#include <QPaintEvent>
#include <QRadialGradient>
#include <QDebug>

#include <time.h>
#include <ctime>
//===================================================================================
// 函数名称 | Frm_Radar()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |构造函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_Radar::Frm_Radar(QWidget *parent)
    : QWidget(parent)
{
    m_radarAreaRect = QRect(-m_uinRadius + 10, -m_uinRadius + 10,2 * (m_uinRadius - 10), 2 * (m_uinRadius - 10));

    connect(&m_rotateTimer, &QTimer::timeout, this, &Frm_Radar::slotRotate);
    m_rotateTimer.setInterval(60);
    m_rotateTimer.start();

    m_scaleFont.setFamily("微软雅黑");
    m_scaleFont.setPixelSize(4);

    m_vecCheckPos = new std::vector<PosStruct>;
    m_vecCheckPos->reserve(10);
}
//===================================================================================
// 函数名称 | ~Frm_Radar()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |析构函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_Radar::~Frm_Radar()
{

}

//===================================================================================
// 函数名称 | paintEvent()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 |绘制事件
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Radar::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);

    int side = qMin(width(), height());
    int x = (width() - side) / 2;
    int y = (height() - side) / 2;

    // 设置ViewPort
    painter.setViewport(QRect(x, y, side, side));
    // 设置窗口 逻辑坐标
    painter.setWindow(QRect(-m_uinRadius, -m_uinRadius, 2 * m_uinRadius, 2 * m_uinRadius));
    painter.setRenderHint(QPainter::Antialiasing);

    drawScale(painter);
    drawBackground(painter);
    drawScanArea(painter);

    for (auto item = m_vecCheckPos->begin(); item != m_vecCheckPos->end(); ++item)
    {
        drawPoint(painter, *item);
    }
}
//===================================================================================
// 函数名称 | drawScan()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 |绘制雷达刻度线
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Radar::drawScale(QPainter &painter)
{
    painter.save();
    painter.setPen(QPen(QColor("#2252E1"), 0));
    painter.setFont(m_scaleFont);
    qreal radius = m_uinRadius - 10;
    int value = 15;
    for(int i = 0; i < 24; i++)
    {
        painter.rotate(360 / 24);
        painter.drawText(QPoint(0, -radius - 4), value == 360 ? "0" : QString::number(value));
        value += 15;
    }

    for(int i = 0; i < 120; i++)
    {
        painter.rotate(3);//旋转3°
        if(i % 5 == 0)
            painter.drawLine(QPoint(0, radius - 5), QPoint(0, radius));
        else
            painter.drawLine(QPoint(0, radius - 2), QPoint(0, radius));
    }

    painter.restore();
}
//===================================================================================
// 函数名称 | drawBackground()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 |绘画雷达区域背景
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Radar::drawBackground(QPainter &painter)
{
    painter.save();

    // 画螺旋环
    painter.setBrush(Qt::NoBrush);
    painter.setPen(QPen(QColor("#29EE47"), 0));
    painter.setCompositionMode(QPainter::CompositionMode_Multiply);
    for (unsigned int i = 0; i < m_uinRadius; i = i + 10)
    {
        painter.drawEllipse(QPoint(0, 0), i, i);
    }

    // 画背景
    QRadialGradient radialGradient(QPoint(0, 0), m_uinRadius, QPoint(0, 0));
    radialGradient.setColorAt(0, QColor("#1B47EA"));
    radialGradient.setColorAt(1, QColor("#2DE3E9"));
    painter.setBrush(radialGradient);
    painter.drawEllipse(m_radarAreaRect);

    painter.restore();
}
//===================================================================================
// 函数名称 | drawScanArea()
//-----------------------------------------------------------------------------------
// 函数输入 |painter画家
//-----------------------------------------------------------------------------------
// 函数功能 |绘制雷达扫描区域
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Radar::drawScanArea(QPainter &painter)
{
    // 画扫描区域
    painter.save();
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
    painter.rotate(m_fRotateAngle);

    QColor color_0("#47D72D"); color_0.setAlpha(200);
    QColor color_2("#47D72D"); color_2.setAlpha(0);

    //绘制扫描线
    painter.setPen(QPen(color_0, 0));
    painter.drawLine(QPoint(0, 0), QPoint(m_uinRadius - 10, 0));

    //绘制扫描线拖尾
    QConicalGradient scanAreaGradient(QPoint(0, 0), 0);
    scanAreaGradient.setColorAt(0.0, color_0);
    scanAreaGradient.setColorAt(1. / 360, color_0);
    scanAreaGradient.setColorAt(40. / 360, color_2);
    painter.setPen(Qt::NoPen);
    painter.setBrush(scanAreaGradient);
    painter.drawPie(m_radarAreaRect, 0, 40 * 16);

    painter.restore();
}

五、全方位雷达扫描

在这里插入图片描述

#include "Frm_ScanTanTan1.h"
#include <QTimer>
#include <QPainter>
#include <QtMath>
#include <QDebug>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>

//===================================================================================
// 函数名称 | Frm_ScanTanTan2()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |构造函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_ScanTanTan1::Frm_ScanTanTan1(QWidget *parent) : QWidget(parent)
{
    //监测点列表
    m_vecCheckPos = new std::vector<PosStruct>;
    m_vecCheckPos->reserve(10);

    //加载图片
    setImage(QPixmap("./Resources/image/IronMan2.jpeg"));

    //动画
    QPropertyAnimation *anim1 = new QPropertyAnimation(this, "");
    anim1->setStartValue(40);
    anim1->setEndValue(50);
    anim1->setDuration(300);
    QPropertyAnimation *anim2 = new QPropertyAnimation(this, "");
    anim2->setStartValue(50);
    anim2->setEndValue(30);
    anim2->setDuration(300);
    QPropertyAnimation *anim3 = new QPropertyAnimation(this, "");
    anim3->setStartValue(30);
    anim3->setEndValue(40);
    anim3->setDuration(300);

    animationGroup = new QSequentialAnimationGroup() ;
    animationGroup->addAnimation(anim1);
    animationGroup->addAnimation(anim2);
    animationGroup->addAnimation(anim3);

    connect(anim1, SIGNAL(valueChanged(QVariant)), this, SLOT(slotUpdateImage(QVariant)));
    connect(anim2, SIGNAL(valueChanged(QVariant)), this, SLOT(slotUpdateImage(QVariant)));
    connect(anim3, SIGNAL(valueChanged(QVariant)), this, SLOT(slotUpdateImage(QVariant)));

    //每隔10msec更新扫描线
    m_timer = new QTimer(this);
    m_timer->setInterval(10);
    m_timer->start();
    connect(m_timer, SIGNAL(timeout()), this, SLOT(slotChangeScan()));

    //每隔10msec更新扩散圈
    m_ringsTimer = new QTimer(this);
    m_ringsTimer->setInterval(100);
    m_ringsTimer->start();
    connect(m_ringsTimer, SIGNAL(timeout()), this, SLOT(slotChangeRing()));

    //每隔60ms更新监测点
    m_checkPointTimer = new QTimer(this);
    m_checkPointTimer->setInterval(60);
    m_checkPointTimer->start();
    connect(m_checkPointTimer,SIGNAL(timeout()), this, SLOT(slotRotatePoint()));



}
//===================================================================================
// 函数名称 | ~Frm_ScanTanTan2()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |析构函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_ScanTanTan1::~Frm_ScanTanTan1()
{
    if(m_vecCheckPos)
    {
        delete m_vecCheckPos;
        m_vecCheckPos = NULL;
    }

}
//===================================================================================
// 函数名称 | mousePressEvent()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |鼠标按下事件
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_ScanTanTan1::mousePressEvent(QMouseEvent *event)
{
    if(!mb_isPressed)
    {
        QPoint pressedPoint =  event->pos();
        QPointF realPos = pressedPoint - rect().center();

        QMatrix qMatrix;
        int width = this->width();
        int height = this->height();
        int side = qMin(width, height);
        qMatrix.scale(side / 200.0, side / 200.0);
        QRegion mEllipse = QRegion(-m_uinRingRadius, -m_uinRingRadius, m_uinRingRadius * 2, m_uinRingRadius * 2, QRegion::Ellipse);
        mEllipse = qMatrix.map(mEllipse);
        if( mEllipse.contains(realPos.toPoint()))
        {
            mb_isPressed = true;
            animationGroup->stop();
            update();
        }
    }

}
//===================================================================================
// 函数名称 | mouseReleaseEvent()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |鼠标松开事件
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_ScanTanTan1::mouseReleaseEvent(QMouseEvent *)
{
    if(mb_isPressed)
    {
        mb_isPressed = false;
        RingData ring;
        ring.uin_radius = m_uinRingRadius;
        ring.uin_alpha = 255;
        ring.f_width = 3;
        m_listRings.push_back(ring);
        animationGroup->start();
        update();
    }

}
//===================================================================================
// 函数名称 | paintEvent()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |绘制函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_ScanTanTan1::paintEvent(QPaintEvent *)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);//圆滑处理斜线
    painter.translate(width / 2, height / 2);
    painter.scale(side / 200.0, side / 200.0);

    //绘制扫描线
    drawScan(&painter);
    //绘制扩散圈
    drawRing(&painter);
    //绘制中间图片
    drawImage(&painter);
    //绘制文本
    drawValue(&painter);
    //绘制监测点
    for (auto item = m_vecCheckPos->begin(); item != m_vecCheckPos->end(); ++item)
    {
        drawPoint(painter, *item);
    }

}

六、摇杆方向盘

在这里插入图片描述

#include "Frm_Rocker.h"
#include <QTimer>
#include <QPainter>
#include <QtMath>
#include <QDebug>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>

//===================================================================================
// 函数名称 | Frm_ScanTanTan2()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |构造函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_Rocker::Frm_Rocker(QWidget *parent) : QWidget(parent)
{


    m_timer = new QTimer(this);

    m_intMouseX = 0;
    m_intMouseY = 0;
    connect(m_timer,&QTimer::timeout,this,[=]{emit sigKeyNumchanged(getKeyNum());});
    connect(this,&Frm_Rocker::sigKeyNumchanged,this,[=](int num){ qDebug("当前位置=%d",num); });

}
//===================================================================================
// 函数名称 | ~Frm_ScanTanTan2()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |析构函数
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
Frm_Rocker::~Frm_Rocker()
{


}
//===================================================================================
// 函数名称 | mousePressEvent()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |鼠标按下事件
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Rocker::mousePressEvent(QMouseEvent *event)
{
    m_intMouseX = event->pos().x() - width() / 2;
    m_intMouseY = event->pos().y() - height() / 2;

    qDebug("m_intMouseX=%d,m_intMouseY=%d",m_intMouseX,m_intMouseY);
    m_timer->start(100);
    mb_isPressed=true;
    update();
}
//===================================================================================
// 函数名称 | mouseReleaseEvent()
//-----------------------------------------------------------------------------------
// 函数输入 |
//-----------------------------------------------------------------------------------
// 函数功能 |鼠标松开事件
//-----------------------------------------------------------------------------------
// 返回值为 |
//-----------------------------------------------------------------------------------
// 函数作者 |xt
//===================================================================================
void Frm_Rocker::mouseReleaseEvent(QMouseEvent *)
{
    m_intMouseX = 0;//width()/2;
    m_intMouseY = 0;//height()/2;
    m_timer->stop();
    mb_isPressed=false;
    emit sigKeyNumchanged(Rock_Stop);
    update();
}
  • 16
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
### 回答1: Qt是一种跨平台的C++开发框架,它提供了丰富的GUI组件库,使得开发者可以轻松地设计和创建各种控件和界面。自定义控件从一定程度上方便了程序的编写,让程序更加直观,使用得当的自定义控件可以让程序增添不少精彩细节。仪表盘是一种比较常见的自定义控件,它可以用来显示实时数据,例如速度,油量,温度等等。下面来简单介绍一下用Qt自定义一个仪表盘的一些步骤。 首先要构思好仪表盘的外观和功能,比如可以考虑盘的大小,采用什么颜色,显示哪些数据等等。 其次,需要用Qt中提供的基础控件(如QPainter、QPoint、QRect)来构建自定义控件的各个部分,包括盘表、指针、刻度等,然后为这些部分设置合适的属性(如颜色、位置、宽度等)。 接着,需要实现控件的数据传递和刷新。一般情况下,会使用定时器或者事件触发来更新控件显示的数据。考虑到仪表盘是一种实时显示数据的控件,所以在设计数据刷新时需要保证刷新频率足够高,否则会出现卡顿、显示延迟等问题。 最后,为了方便其他的开发者使用该自定义控件,可以将其打包成独立的Qt插件,或者直接将自定义控件的源代码公开发布。 以上就是简单的Qt自定义控件仪表盘的一些步骤,开发者可以根据自己的需求进行相应更改和优化。总之自定义控件并不是一件简单的事情,但是如果能够掌握好最基本的知识,就能够创造出更加精美、实用的自定义控件。 ### 回答2: Qt自定义控件仪表盘可以用于需要展示数据的界面设计。通过自定义仪表盘,可以实现不同样式和功能的展示,并且能够满足不同场景下的需求。 在Qt中,仪表盘的设计可以通过绘图、圆弧、指针和动画的实现,使得界面更加直观、美观,也更加容易被用户理解和操作。可以通过Qt提供的QPainter绘图工具绘制圆弧,也可以通过QTimer控制指针的动画效果。 另外,仪表盘也是可以与其他控件进行绑定的。通过信号与槽的机制,可以将仪表盘的数值与其他控件进行绑定,实现更加复杂的界面功能。 需要特别注意的是,仪表盘的设计需要考虑到不同屏幕分辨率的适配性。通过使用Qt提供的屏幕适配机制,可以实现不同分辨率下的仪表盘展示效果。 总之,Qt自定义控件仪表盘是一个非常实用、优雅的设计元素,可以帮助开发者快速开发出漂亮的界面,并且提高用户体验。 ### 回答3: Qt是一个强大的C++跨平台框架,自带了很多常用的UI控件,但是有时候我们也需要自定义一些控件来满足我们的需求。今天我们来介绍一下如何使用Qt自定义一个仪表盘控件。 首先我们需要继承QWidget类,命名为Dashboard。然后我们需要在Dashboard的构造函数中初始化一些常量,比如外部圆弧的宽度、内部圆弧的半径等等。接着我们需要重写paintEvent函数,绘制仪表盘的外部圆弧、刻度、指针等等,具体绘制方式可以根据需求灵活设置。 为了使仪表盘可以在Qt Designer中拖拽使用,我们需要在Dashboard类中加入QIB_DESIGNER_EXPORT_WIDGETS宏。最后在.pro文件中添加如下代码: ``` QT += designer TARGET = Dashboard TEMPLATE = lib HEADERS += Dashboard.h SOURCES += Dashboard.cpp QIB_DESIGNER_EXPORT_WIDGETS(Dashboard) ``` 这样我们就可以在Qt Designer中使用Dashboard自定义控件了。当然,使用自定义控件也需要相应的信号槽机制来进行交互操作。 总的来说,自定义控件可以更好地满足我们的需求,同时也可以提高界面的美观度。在自定义控件的过程中,我们要考虑到控件的可扩展性、易用性以及代码的可维护性等方面,并在不断地改进和优化中,不断提高自己的技术水平。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

何以问天涯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值