Qt QML 自绘GPS方位校北仪控件

46 篇文章 21 订阅
10 篇文章 0 订阅

        校北仪用于显示不同设备与参照方位之间的误差夹角,如果仅仅使用柱状图显示多个不同设备误差的数值,数据不够直观表示,因此自己画一个,效果如图:

        该控件使用QQuickPaintedItem进行绘制后在QML中进行使用,相关部分参数已提供设置接口供QML中调用,如果该控件需要在QWidget中使用,将QQuickPaintedItem修改为QWidget即可。在Demo中演示了如何添加不同方位夹角,不同颜色的指针,并根据指针名称动态修改数据。控件提供的相关接口如下,如果有其他接口需求,可下方留言提供建议,本人不断完善。

属性:

title:设置表盘中文字内容

titlePoint:设置表盘中文字大小

beginAngle:设置表盘刻度起始方位角,默认为(330)

spanAngle:设置表盘刻度拓展角度,默认为(240)

dialTextPoint:设置表盘数字大小

方法:

void appendPointer(const qreal angle, const QColor color, const QString name):往控件中添加新的数据指针【angle:方位夹角(取值范围:-3~3);color:指针颜色;name:指针名称】

void changePointerData(const QString name,const qreal angle):根据指针名修改指针数值

void clear():清除表盘中所有数据指针

void remove(const QString name):根据指针名删除指针

void pointerVisible(const QString name, const bool visible):根据指针名进行隐藏/显示

void showAllPointer():显示所有指针

void hideAllPointer():隐藏所有指针

 Demo地址GitHub:

https://github.com/zjgo007/QmlDemo/tree/master/Azimuthhttps://github.com/zjgo007/QmlDemo/tree/master/Azimuth

Demo地址csdn下载:

https://download.csdn.net/download/zjgo007/75943564https://download.csdn.net/download/zjgo007/75943564

部分代码:

绘制paint:

void AzimuthDial::paint(QPainter *painter)
{
    painter->setPen(Qt::NoPen);
    painter->setRenderHint(QPainter::Antialiasing);
    painter->setRenderHint(QPainter::SmoothPixmapTransform);
    painter->translate(this->width()/2,this->height()/2);
    radius = qMin(this->width(),this->height())/2;
    drawBgLightColor(painter);
    drawScaleBgColor(painter);
    drawSlideBarColor(painter);
    drawDialCenterCross(painter);
    drawDialRule(painter);
    drawDialText(painter);
    drawPointer(painter);
    drawDialCenterColor(painter);
}

绘制背景颜色:

void AzimuthDial::drawBgLightColor(QPainter *painter)
{
    QConicalGradient conicalBrush(0,0,90);
    conicalBrush.setColorAt(0,mBgLightColor);
    conicalBrush.setColorAt(0.5,mBgLightColor);
    conicalBrush.setColorAt(0.12,mBgLightColor);
    conicalBrush.setColorAt(0.88,mBgLightColor.darker(40));
    conicalBrush.setColorAt(0.4,mBgLightColor.darker(30));
    conicalBrush.setColorAt(0.6,mBgLightColor.darker(30));
    conicalBrush.setColorAt(0.25,mBgLightColor.darker(160));
    conicalBrush.setColorAt(0.75,mBgLightColor.darker(160));
    conicalBrush.setColorAt(0.1,mBgLightColor);
    painter->setBrush(conicalBrush);
    painter->drawEllipse(QPointF(0,0),radius*0.95,radius*0.96);
}

绘制表盘刻度背景条颜色:

void AzimuthDial::drawSlideBarColor(QPainter *painter)
{
    QConicalGradient barTintColor(0,0,90);
    barTintColor.setColorAt(0,"#4d00fa9a");
    barTintColor.setColorAt(0.125,"#4d00ffff");
    barTintColor.setColorAt(0.25,"#4dffd700");
    barTintColor.setColorAt(0.375,"#4dff4500");
    barTintColor.setColorAt(0.5,"#4d00fa9a");
    barTintColor.setColorAt(0.625,"#4dff4500");
    barTintColor.setColorAt(0.75,"#4dffd700");
    barTintColor.setColorAt(0.875,"#4d00ffff");
    barTintColor.setColorAt(1,"#4d00fa9a");

    QRectF rectT(-0.9*radius,-0.9*radius,radius*1.8,radius*1.8);
    qreal subRadiusT = (radius*0.79);
    painter->setBrush(barTintColor);
    QPainterPath piePathT;
    piePathT.arcMoveTo(rectT,mStartAngle);
    piePathT.arcTo(rectT,mStartAngle,mSpanAngle);
    piePathT.lineTo(0,0);
    QPainterPath subPathT;
    subPathT.addEllipse(QPointF(0,0),subRadiusT,subRadiusT);
    piePathT = piePathT-subPathT;
    painter->drawPath(piePathT);

    QConicalGradient barColor(0,0,90);
    barColor.setColorAt(0,"#00fa9a");
    barColor.setColorAt(0.125,"#00ffff");
    barColor.setColorAt(0.25,"#ffd700");
    barColor.setColorAt(0.375,"#ff4500");
    barColor.setColorAt(0.5,"#00fa9a");
    barColor.setColorAt(0.625,"#ff4500");
    barColor.setColorAt(0.75,"#ffd700");
    barColor.setColorAt(0.875,"#00ffff");
    barColor.setColorAt(1,"#00fa9a");

    QRectF rect(-0.86*radius,-0.86*radius,radius*1.72,radius*1.72);
    qreal subRadius = (radius*0.83);
    painter->setBrush(barColor);
    QPainterPath piePath;
    piePath.arcMoveTo(rect,mStartAngle);
    piePath.arcTo(rect,mStartAngle,mSpanAngle);
    piePath.lineTo(0,0);
    QPainterPath subPath;
    subPath.addEllipse(QPointF(0,0),subRadius,subRadius);
    piePath = piePath-subPath;
    painter->drawPath(piePath);
}

绘制中心十字:

void AzimuthDial::drawDialCenterCross(QPainter *painter)
{
    qreal crossRadiusBrush = radius*0.65;

    painter->setPen(Qt::NoPen);
    QLinearGradient gradientH(0,-10,0,10);
    QLinearGradient gradientV(-10,0,10,0);
    gradientH.setColorAt(0,"#3300fa9a");
    gradientH.setColorAt(0.5,"#00fa9a");
    gradientH.setColorAt(1,"#3300fa9a");
    gradientV.setColorAt(0,"#3300fa9a");
    gradientV.setColorAt(0.5,"#00fa9a");
    gradientV.setColorAt(1,"#3300fa9a");
    painter->setBrush(gradientH);
    painter->drawRect(-crossRadiusBrush,-10,crossRadiusBrush*2,20);
    painter->setBrush(gradientV);
    painter->drawRect(-10,-crossRadiusBrush,20,crossRadiusBrush);

}

绘制表盘刻度线,整数刻度时使用长三角型着重表示:

void AzimuthDial::drawDialRule(QPainter *painter)
{
    QPen pen;
    pen.setColor(mDialRuleColor);
    pen.setWidth(2);
    painter->setBrush(mDialRuleColor);
    QPainterPath dialRulePath;

    qreal intervalAngle = mSpanAngle/30;
    qreal pointAngle = mSpanAngle/6;
    qreal dialRadius = radius*0.9;
    qreal subDiaRadius = radius*0.83;
    qreal pointDiaRadius = radius*0.79;

    //绘制标尺刻度线
    for(int a=0;a<=mSpanAngle;a+=intervalAngle){
        qreal currentAngle = a+mStartAngle;
        qreal r = qDegreesToRadians(currentAngle);
        const qreal x1 = dialRadius*cos(r);
        const qreal y1 = -dialRadius*sin(r);
        const qreal x2 = subDiaRadius*cos(r);
        const qreal y2 = -subDiaRadius*sin(r);
        dialRulePath.moveTo(x1,y1);
        dialRulePath.lineTo(x2,y2);
    }
    painter->setPen(pen);
    painter->drawPath(dialRulePath);

    //绘制整角度时标尺刻度线样式(三角形)旋转坐标轴绘制
    qreal pointStartAngle = mStartAngle>180 ? (mStartAngle-360):mStartAngle;
    const QPointF pointDial[4]={
        QPointF(pointDiaRadius,0),
        QPointF(pointDiaRadius,-0),
        QPointF(dialRadius,-1),
        QPointF(dialRadius,1)
    };

    for(int i=0;i<=6;i++){
        qreal rotateAngle = pointStartAngle+i*pointAngle;
        painter->rotate(-rotateAngle);
        painter->drawConvexPolygon(pointDial,4);
        painter->rotate(rotateAngle);
    }
}

绘制表盘数字:

void AzimuthDial::drawDialText(QPainter *painter)
{
    QPen pen;
    pen.setColor(mDialTextColor);
    pen.setWidth(2);
    painter->setFont(QFont("Euphemia",mDialTextPoint,QFont::DemiBold));
    qreal textDiaRadius = radius*0.71;
    qreal textAngle = mSpanAngle/6;
    qreal textStartAngle = mStartAngle>180 ? (mStartAngle-360):mStartAngle;
    const QStringList labels = {"3","2","1","0","1","2","3"};
    for(int i=0;i<=6;i++){
        qreal currentAngle = textStartAngle+i*textAngle;
        qreal r = qDegreesToRadians(currentAngle);
        const qreal x = textDiaRadius*cos(r);
        const qreal y = -textDiaRadius*sin(r);
        painter->drawText(QRectF(x-15,y-10,30,20),Qt::AlignHCenter|Qt::AlignVCenter,labels.at(i));
    }
}

绘制数值指针:

void AzimuthDial::drawPointer(QPainter *painter)
{
    painter->setPen(Qt::NoPen);
    painter->setBrush(mDialPointerColor);
    qreal pointDiaRadius = radius*0.6;
    qreal pointBottomRadius = radius*0.1;
    const QPointF pointDial[4]={
        QPointF(-pointBottomRadius,3),
        QPointF(-pointBottomRadius,-3),
        QPointF(pointDiaRadius,-1),
        QPointF(pointDiaRadius,1),
        };

    for(auto data : mVector){
        qreal angle = data.angle;
        QColor color = data.color;
        QString name = data.name;
        qreal r = 90 - angle*(mSpanAngle/6);
        painter->rotate(-r);
        painter->setBrush(color);
        painter->drawConvexPolygon(pointDial,4);
        painter->rotate(r);
    }
}

绘制中心圆:

void AzimuthDial::drawDialCenterColor(QPainter *painter)
{

    qreal centerRadius = radius*0.08;
    QRadialGradient radial(0,0,centerRadius,0,0);
    radial.setColorAt(1,mCenterColor.lighter(170));
    radial.setColorAt(0.90,mCenterColor.lighter(150));
    radial.setColorAt(0.82,mCenterColor.lighter(130));
    radial.setColorAt(0.7,mCenterColor);
    painter->setBrush(radial);
    painter->drawEllipse(QPointF(0,0),centerRadius,centerRadius);
    //绘制标签
    QPen pen;
    pen.setColor(mDialTextColor);
    pen.setWidth(2);
    painter->setPen(pen);
    painter->setFont(QFont("微软雅黑",mTitleTextPoint,QFont::DemiBold));
    painter->drawText(QRectF(-100,centerRadius*2,200,60),Qt::AlignHCenter|Qt::AlignVCenter,mTitle);

    QImage pixmapGPS(":/gps.png");
    painter->drawImage(QRectF(-centerRadius,-centerRadius,centerRadius*2,centerRadius*2),pixmapGPS,QRectF(0,0,79,79));
    QImage pixmapLogo(":/logo.png");
    painter->drawImage(QRectF(-centerRadius*3.2,centerRadius*2+70,centerRadius*6.4,centerRadius*3),pixmapLogo,QRectF(0,0,300,128));
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
### 回答1: Qt QML仪表Demo是一个用于展示仪表效果的示例程序,通过使用Qt框架中的QML语言进行开发。QML是一种用于构建用户界面的声明式语言,它可以与C++代码无缝交互,并且可以跨平台运行。 这个仪表Demo通常包含一个圆形的仪表盘,上面显示着一些指针和刻度,用于表示某种状态或数值。这个示例程序可以用来演示一些实际应用场景,如车辆仪表盘、仪器仪表等。 在QML文件中,我们可以定义一个圆形的画布并在上面绘制各种图形元素。例如,我们可以添加一个圆形的外环作为仪表盘的边框,然后在中间添加一个圆形的刻度盘,并绘制出不同的刻度线。接着,我们可以添加指针和数字等元素,来显示具体的数值。 在QML中,我们可以使用一些内置的属性和表达式来实现各种动画效果。比如,我们可以定义一个动画来实现指针的旋转,使其根据仪表盘上的值进行相应的角度调整。还可以通过属性绑定来实时更新仪表盘的数值显示。 除了基本的仪表功能,我们还可以通过QML的扩展性来添加更多的交互功能。例如,通过添加鼠标事件处理器或触摸事件处理器,我们可以让用户通过拖动、滑动等方式来手动调整仪表盘的数值。 总之,Qt QML仪表Demo是一个通过使用Qt框架中的QML语言开发的示例程序,用于展示仪表效果。它可以帮助开发者更好地理解和学习QML的使用方法,并将其应用于实际项目中。 ### 回答2: Qt QML仪表Demo是一个使用Qt Quick绘制仪表盘界面的示例程序。QML是一种声明性语言,用于构建基于Qt的用户界面。 该示例程序展示了如何使用QML绘制一个具有平滑动画效果的仪表盘界面。在这个示例中,仪表盘界面由一个圆形背景、一个指针和一些标签组成。 首先,通过QML的绘图元素Path绘制一个圆形背景。可以设置背景的颜色、半径和边框。然后,使用Item元素嵌套一个Rectangle元素,用作指针。可以根据仪表盘当前值计算指针的角度,并将其旋转到正确的位置。 除了绘制背景和指针,示例中还包含一些标签,用于显示仪表盘的范围和单位。这些标签可以使用Text元素和属性绑定来实现。可以根据需要设置标签的颜色、大小和位置。 示例程序还包含一些动画效果,用于平滑地过渡指针的位置。可以使用Behavior元素和属性动画来定义这些效果。例如,可以定义一个角度动画,使指针在数值改变时顺时针或逆时针旋转到新的位置。 为了实现用户交互,示例程序还使用了一些QML的交互元素,如Slider和Button。可以通过Slider来改变仪表盘的数值,从而实现指针的动态变化。而Button可以用于重置仪表盘的数值。 综上所述,Qt QML仪表Demo是一个使用Qt Quick绘制仪表盘界面的示例程序,通过展示QML的绘图元素、属性绑定、动画效果和用户交互来实现这个功能。 ### 回答3: Qt QML仪表Demo是一个基于Qt Quick和QML语言编写的示例应用程序,用于展示仪表盘的功能和样式。 该示例应用程序主要由以下几个部分组成: 1. 仪表盘组件:通过使用Qt Quick Controls组件库中的样式,可以创建一个美观和交互性强的仪表盘界面。例如,可以使用圆形进度条来显示速度、转速等信息,并使用指针在刻度上指示当前数值。 2. 数据模型:为了展示仪表盘的功能,需要使用数据模型来模拟一些实际的数值。可以创建一个虚拟的数据模型,包含一些属性,如速度、转速等,并使用属性绑定机制将这些属性与仪表盘组件上的对应属性绑定起来。 3. 用户交互:通过用户交互,可以实现一些仪表盘的交互功能。例如,可以通过滑动或点击来改变仪表盘上的数值,或者通过A/B按钮来切换仪表盘的显示模式。 4. 动画效果:使用Qt Quick的动画系统,可以为仪表盘组件添加一些动画效果。例如,在数值变化时可以添加一个渐变动画效果,使仪表盘的指针从一个数值平滑过渡到另一个数值。 Qt QML仪表Demo不仅可以作为一个示例应用程序来展示如何创建仪表盘界面,还可以作为一个基础框架,用于开发具有仪表盘功能的实际应用程序。通过修改和扩展仪表盘组件、数据模型和用户交互等部分,可以满足不同应用场景的需求。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

喵喵叫的猴

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

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

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

打赏作者

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

抵扣说明:

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

余额充值