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

2023-05-16

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

        该控件使用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));
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Qt QML 自绘GPS方位校北仪控件 的相关文章

  • 帮助使用 GPS 坐标,Android

    我正在使用此代码来获取我的位置并在屏幕上打印坐标 package com example alpha import android app Activity import android content Context import and
  • 使用纬度/经度计算从 A 点到线段的距离

    我正在开发一个使用 GPS 的 Android 应用程序 我想知道如果 新位置 C 点 距离线段 AB 太远 是否有办法可以丢弃 GPS 位置数据 我正在使用发现的点到线段公式在维基百科上 http en wikipedia org wik
  • 谷歌地图定位是如何工作的?

    我的问题是谷歌地图或移动 GPS 如何找到我的当前位置 读完本文后我的高层次理解article http www physics org article questions asp id 55就是 GPS接收器通过这些卫星获取位置坐标 该位
  • Android 中的 GPS 超时

    在黑莓中 我们使用超时来获取位置 这样如果它在这么长时间内没有重新调整位置 我们就会知道 但是在Android中 没有超时的概念 任何人都可以告诉我们替代方案 我们可以发现 在这么长时间之后 GPS没有位置更新 您可以使用两个线程来实现此超
  • 如何在C++、Qt、QML、Blackberry 10 Cascades Beta 3 SDK中制作图表/图形(如折线图、条形图、圆形图)等?

    我需要知道如何在 Blackberry 10 Cascades Beta 3 SDK QML Qt C 中制作图表 图表 如果有人可以向我展示一个例子或向我指出一些可以告诉我如何做到这一点的东西 我将不胜感激 您应该查看 QChart js
  • requestLocationUpdates minTime 参数用途

    我正在创建一个应用程序 用于教育目的 它每 30 分钟记录一次用户的位置 并使用户能够查看地图上的所有位置 我不希望更新频率超过 30 分钟 但事实确实如此 这就是我的称呼requestLocationUpdates locationMan
  • 通过对 XmlHttpRequest (REST) 的响应在 QML 中显示图像

    我需要从 REST API 调用中获取 jpeg 图像 我使用 XMLHttpRequest 因为请求需要身份验证标头 即我不能只创建一个图像并将源设置为带有 user passwd url 的 URL 我认为我可以通过将 REST 数据设
  • 我的 QSqlQueryModel 不在列表视图中显示数据

    我正在玩 QSqlQueryModel 但我现在完全陷入困境 我一整天都在寻找解决方案 但到目前为止还没有运气 我所做的工作是它从我的 sqlite 数据库中提取数据 但由于某种原因我无法在列表视图中显示它 我的角色名似乎不存在 对于我从数
  • QML 项目的 QtCreator 中未启用“运行”按钮

    我在Windows XP上使用基于QT 4 7 4 32位 的QTCreator 2 2 1 我从 new gt QML 项目菜单创建了一个 QML 项目 但 RUN 按钮未启用 如何运行 QML 项目 您是否创建了新的 QML 文件而不是
  • Swift 将十进制坐标转换为度、分、秒、方向

    我怎样才能将其转换为快速 我最好的猜测是所有 int 都变成了 var 删除所有导致 的 此外 如果有的话可以给我指出一个很好的来源来了解事物如何转换 那就太好了 NSString coordinateString int latSecon
  • 从 QML 实例化 C++ 对象会产生巨大的内存使用开销

    实例化一个QObjectC 堆中的派生类为每个对象提供了大约 160 个字节 通过注册相同的对象qmlRegisterType 用于从 QML 创建并通过以下方式动态创建对象createObject 每个对象给我 2000 多个字节 这是完
  • 向 tk103 GPS 跟踪器发送命令

    我正在使用 php 开发实时 GPS 跟踪器 Web 应用程序 跟踪器参考号是tk103 我可以从跟踪器接收信息并将其存储到数据库中 设备的 GPRS 模式已启用 我的问题是 如何使用 php ini 将命令从服务器发送到设备 提前致谢 这
  • 如何在 QtQuick 2 中对 QML TableView 进行排序?

    我想使用 Qt 5 1 实现具有自定义角色的可排序 TableView 但我不知道当用户单击标题时该怎么做才能对其进行排序 在我的 Qt pro 文件中 我添加了 android ios blackberry qtHaveModule wi
  • 是否可以自定义区域形状?核心位置

    例如 至少我想要一个正方形 矩形 道路的形状作为我的区域 不它不是 根据文档 目前唯一的区域类是 CLCircularRegion 显然是圆形 和 CLBeaconRegion 基于与 iBeacon 的接近度 未来苹果可能会添加对自定义形
  • QML改变图像颜色

    我搜索了如何对图像进行着色 格式为 svg 或 png 我尝试用一 个填充图像的矩形覆盖我的图像 但由于我的图像不是矩形 它会给整个矩形着色 而不仅仅是图像 可以用qml改变图像颜色吗 或者 是否可以使用 QPixmap 更改 qt 使用
  • 在 Windows 上以 QML 播放 RTSP 视频

    我正在尝试将 QML 中的 RTSP 流播放到视频标签中 如下所示 Repeater model 8 Video Layout fillWidth true Layout fillHeight true fillMode VideoOutp
  • 为什么anchors.centerIn不适用于Column元素?

    我有这段 QML 代码 Column spacing units gu 2 anchors fill parent centerIn parent Row spacing units gu 4 Row spacing units gu 4
  • 在另一个中使用 QAbstractListModel

    我在尝试使用 Qt QML 为我的应用程序开发数据模型时遇到问题 我已经用过一个QAbstractListModel能够将海关数据模型从 C 传递到 QML 并且它对于简单模型 例如基于字符串和布尔的模型 来说就像一个魅力 但现在我需要建立
  • 如何在Android中获取当前位置[重复]

    这个问题在这里已经有答案了 我在使用 Android 定位系统的网络提供程序获取当前位置坐标时遇到麻烦 已经阅读了大量教程并在我的项目中实现了 4 或 5 个现有类 所有这些类都给了我最后的坐标 但不是当前的坐标 我很确定这个问题是我所缺少
  • 如何在android中以编程方式启用位置访问?

    我正在开发与地图相关的 Android 应用程序 如果位置服务未启用显示对话框提示 我需要在客户端开发中检查位置访问是否启用 如何在android中以编程方式启用 位置访问 使用下面的代码进行检查 如果禁用 将生成对话框 public vo

随机推荐

  • ssh Key exchange was not finished sshd

    报错 xff1a ssh Key exchange was not finished 则需修改sshd文件 链接 xff1a Key exchange was not finished connection is closed近期遇到这个错
  • C++类成员冒号初始化以及构造函数内赋值

    通常我们对类成员进行 初始化 有两种方式 xff1a 1 构造函数后面跟冒号 xff1b 2 构造函数里面对成员进行赋值 有些人不太注意这个小细节 xff0c 或者根本不知道他们的区别 xff0c 认为两种方式是一样的 这个误解有时可能会对
  • Web项目中pom.xml中<Project>爆红

    artifactId 39 with value 39 项目名 39 does not match a valid id pattern 主要是项目名中 lt artifactId gt 项目名 lt artifactId gt 项目名带空
  • 《自动化学报》踩坑心得

    LATEX使用于文本编辑器此次我是用的是latex安装方法是TeXLive 43 WinEdt 模板使用的是自动化学报模板 xff0c 使用的是中文模板 xff0c for paper in Chinese 文件 xff0c 打开之后选择打
  • 个人介绍以及课程期待

    本人朱杰 xff0c 现为北京理工大学大二学生 xff0c 主攻软件工程 xff0c 性格开朗 现在正在学习软件工程基础 xff0c 特写此文 xff0c 以明志 我希望能通过这门课能够更系统的了解软件工程 xff0c 之前对此的认知都是很
  • 向日葵提示‘’连接断开‘’解决方法(已解决非常好用)终端执行 xhost + 即可

    1 这个是授权访问 xff0c 一般输入xhost 43 即可 向日葵远程桌面提示连接断开解决方法 终端执行 xhost 43 即可 xhost 43 是使所有用户都能访问Xserver xhost 43 ip使ip上的用户能够访问Xser
  • 对vector使用指针

    include lt stdio h gt include lt iostream gt include lt vector gt using namespace std int main vector lt int gt a b c fo
  • 岁月划过生命线(我的2013-大二.上)

    岁月划过生命线 大二 上 又一次大清早被红马甲查赶出被窝 xff0c 让哥光着屁股就跑到隔壁宿舍去了 xff0c 真心恨死他们 这是一篇最早写于 2013 11 26 日的日志 xff0c 通过后来不断地增删改 xff0c 来总结 xff0
  • 带中文字库的12864LCD显示程序

    带中文字库的12864LCD显示程序 include lt reg52 H gt include lt intrins H gt define uchar unsigned char define uint unsigned int sbi
  • QML 自定义Legend(点击Legend隐藏/显示)

    QML ChartView中提供了默认的Legend xff0c 可对图例进行一些简单的例如颜色 字体等的设置 xff0c 但是当需要图例具有个性化的功能时 xff08 如单击时隐藏或显示 xff09 时 xff0c 就需要使用自定义的Le
  • Qt多线程中使用QTimer(常见问题汇总)

    我们经常需要将一些耗时的工作在子线程中进行 xff0c 同时在子线程中又需要用到循环事件时 xff0c 一种方法使用While sleep 进行线程控制 另一种创建一个QTimer对象 xff0c 使用信号与槽机制将信号timeout 与相
  • Qt 中使用 VLC-Qt 播放网络视频流(附实例)

    VLC Qt库 xff1a 一个在libVLC基础上结合了Qt框架的开源库 它提供了媒体播放的视频 音频处理控制的核心类 xff0c 并提供基于QWidget和QML的GUI框架 效果图 xff1a 官网地址 xff1a Quickly c
  • 微信小程序云开发处理微信支付成功的回调函数(云函数实现)

    在使用微信小程序开发微信支付功能时 xff0c 使用云开发中的微信支付云调用 xff0c 将商品信息 支付价格等信息传入云函数中 xff0c 并在返回的字段payment获取wx requestPayment接口所需要的所有信息 通过此方法
  • 前端 大数据 echarts

    https echarts apache org handbook zh basics download
  • Qt使用钩子后台监控键盘并在界面中响应

    当我们的Qt程序需要在后台监听键盘的操作或者屏蔽键盘的操作时 xff0c 就需要用到系统的API xff0c 因此用到Windows钩子 xff0c 下面简单介绍下使用钩子监控键盘按键 xff0c 原理较简单 xff0c 代码上我都注释了
  • Qt 5.15.2添加msvc2019编译环境(不需要安装VS)

    安装Qt5 15 2 只能在线安装 xff0c 安装时候注意勾选MSVC 2019 64 bit支持 xff0c 其他的根据自己需要勾选 xff0c 点击下一步等待Qt安装完毕 xff0c 此时QtCreator中Kits里Desktop
  • QML Map中使用Open Street Map(osm)离线地图(瓦片地图加载方式)

    当使用QML Map显示地图时 xff0c 有时候无法连接互联网 xff0c 因此需要使用离线模式加载地图 xff0c 加载离线地图瓦片时 xff0c 需要为插件设置参数信息 xff0c 其中name表示参数字段 xff0c value表示
  • Qt Creator 无法编辑Qml界面,报错:“Qt Quick emulation layer crashed”

    今日在Qml界面编辑中 xff0c 突然无法使用设计师编辑器 xff0c 并报错如图 xff1a 代码定位也无法定位到错误的位置处 xff0c 通过注释代码的方式检查后 xff0c 发现错误产生原因是某个部件设置了两个状态State xff
  • QML中使用QPen设置组件边框(以CandlestickSeries为例)

    QML中提供了很多组件是由C 43 43 中绘制而注册到QML中使用的 xff0c 这些组件采用QPen绘制组件边框 xff0c 这样的组件均可使用返回QPen的方法设置边框样式 例如CandlestickSeries就提供了数据展示的蜡烛
  • Qt QML 自绘GPS方位校北仪控件

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