15. Canvas制作汽车油耗仪表盘

1. 说明

本篇文章在14. 利用Canvas组件制作时钟的基础上进行一些更改,想查看全面的代码可以点击链接查看即可。
效果展示:
在这里插入图片描述

2. 整体代码

import QtQuick 2.15
import QtQuick.Controls 2.15

Item{
    id:root
    implicitWidth: 400
    implicitHeight: implicitWidth

    // 尺寸属性
    property real outerCircleRadius:root.width / 2.05
    property real innerCircleRadius:root.width / 2.05

    // 颜色属性
    property color bgColor:Qt.rgba(0,0,0,0)
    property color outerColor:"black"
    property color innerColor:"black"
    property color innerRootColor:"lightSlateGray"
    property color innerLineColorL:Qt.rgba(1,1,1,1)
    property color innerLineColorS:Qt.rgba(1,1,1,0.8)
    property color textColor:"white"
    property color secondLineColor:"red"

    // 指针
    property var seconds
    property alias secondsAngle:secondLine.angle

    // 绘制背景
    Canvas{
        id:bgCircle
        width: root.width
        height: root.height
        anchors.centerIn: parent
        onPaint: {
            // 绘制背景
            var ctx = getContext("2d")  
            ctx.save()
            ctx.lineWidth = root.width/50   
            ctx.fillStyle = bgColor
            ctx.beginPath()
            ctx.arc(root.width/2,root.height/2,outerCircleRadius,Math.PI * (5/6),Math.PI * (1/6))
            ctx.fill()
            ctx.restore()
        }
    }
    // 绘制圆环轮廓
    Canvas{
        id:outerCircle
        width: root.width
        height: root.height
        anchors.centerIn: parent
        onPaint: {
            var ctx = getContext("2d")  //创建画师
            //为画师创建画笔并设置画笔属性
            ctx.lineWidth = root.width/50   //设置画笔粗细
            ctx.strokeStyle = outerColor    //设置画笔颜色
            ctx.beginPath()     //每次绘制调用此函数,重新设置一个路径
            // 按照钟表刻度进行划分,一圈是Math.PI * 2,分成12个刻度,每个刻度占用 1/6
            // canvas绘制圆弧,是按照顺时针绘制,起点默认在三点钟方向
            ctx.arc(root.width/2,root.height/2,outerCircleRadius,Math.PI * (5/6),Math.PI * (1/6))
            ctx.stroke()    //根据strokeStyle对边框进行描绘
        }
    }
    // 绘制秒针线
    Canvas{
        id:secondLine
        width: root.width
        height: root.height
        anchors.centerIn: parent
        property real angle:Math.PI * (8/6)
        onPaint: {
            var ctx = getContext("2d")
            ctx.clearRect(0,0,width,height)
            ctx.save()
            ctx.beginPath()
            ctx.lineWidth = root.width/100
            ctx.strokeStyle=secondLineColor
            // 平移坐标点(注意:坐标系原点先平移,再旋转)
            ctx.translate(root.width/2,root.height/2)
            // 旋转坐标系
            ctx.rotate(angle)
            // 坐标原点变化之后再进行实际的绘图
            ctx.moveTo(0,-10);
            ctx.lineTo(0,outerCircleRadius / 1.5);
            ctx.stroke()
            ctx.restore()
        }
    }
    // 绘制圆环内衬
    Canvas{
        id:innerCircle
        width: root.width
        height: root.height
        anchors.centerIn: parent
        property real endAngle:Math.PI * (12/6)
        onPaint: {
            var ctx = getContext("2d")  
            ctx.save()
            ctx.lineWidth = root.width/50   
            ctx.strokeStyle = innerColor     
            ctx.beginPath()     
            ctx.arc(root.width/2,root.height/2,innerCircleRadius,Math.PI * (5/6),Math.PI * (1/6))
            ctx.stroke()    
            ctx.restore()

            // 绘制指针根部圆圈
            ctx.save()
            ctx.lineWidth = root.width/50   
            ctx.fillStyle = innerRootColor
            ctx.beginPath()
            ctx.arc(root.width/2,root.height/2,innerCircleRadius/8,0,endAngle)
            ctx.fill()
            ctx.restore()
        }
    }
    // 绘制刻度线
    Canvas{
        id:innerLine
        width: root.width
        height: root.height
        anchors.centerIn: parent
        property real lineNums:60
        onPaint: {
            var ctx = getContext("2d")  
            for (var i = 0; i <= lineNums; ++i){
                if(i > 5 && i < 25){
                    continue
                }
                ctx.beginPath();
                var angle = 2 * Math.PI / 60 * i;
                var dx = Math.cos(angle)*(outerCircleRadius-15);
                var dy = Math.sin(angle)*(outerCircleRadius-15);
                var dx2 = Math.cos(angle)*(outerCircleRadius-7);
                var dy2 = Math.sin(angle)*(outerCircleRadius-7);
                if (i % 5 === 0 && i != 25 && i != 30){
                    ctx.lineWidth = root.width/100
                    ctx.strokeStyle = innerLineColorL
                }else if(i >= 25 && i <= 30){
                    ctx.strokeStyle = "red"
                }
                else{
                    ctx.lineWidth = root.width/200
                    ctx.strokeStyle = innerLineColorS
                }
                ctx.moveTo(root.width/2+dx,root.height/2+dy);
                ctx.lineTo(root.width/2+dx2,root.height/2+dy2);
                ctx.stroke();
            }
        }
    }
    // 绘制数字
    Canvas{
        id:drawText
        width: root.width
        height: root.height
        anchors.centerIn: parent
        property var numbers : [1,2,3,4,5,6,7,8,9,10,11,12]
        onPaint: {
            var ctx = getContext("2d")
            ctx.font = "18px Arial";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            for(var i = 0; i < 12; ++i)
            {
                ctx.fillStyle = textColor
                var angle = 2 * Math.PI / 12 * numbers[i] - 3.14 / 2;
                var dx = Math.cos(angle)*(outerCircleRadius-35);
                var dy = Math.sin(angle)*(outerCircleRadius-35);
                switch(i){
                case 3:
                    ctx.fillText(1,root.width/2 + dx,root.height / 2 + dy);
                    ctx.fill()
                    break
                case 7:
                    ctx.fillText(0,root.width/2 + dx,root.height / 2 + dy);
                    ctx.fill()
                    break
                case 11:
                    ctx.fillText("1/2",root.width/2 + dx,root.height / 2 + dy);
                    ctx.fill()
                    break
                default:
                    break
                }
            }
        }
    }
    Image{
        id:iconImg
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top
        anchors.topMargin: 5
        scale: 0.25
        source: "qrc:/油箱.png"
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/84477.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序使用云存储和Markdown开发页面

最近想在一个小程序里加入一个使用指南的页面&#xff0c;考虑到数据存储和减少页面的开发工作量&#xff0c;决定尝试在云存储里上传Markdown文件&#xff0c;微信小程序端负责解析和渲染。小程序端使用到一个库Towxml。 Towxml Towxml是一个可将HTML、Markdown转为微信小程…

Android2:构建交互式应用

一。创建项目 项目名Beer Adviser 二。更新布局 activity_main.xml <?xml version"1.0" encoding"utf-8"?><LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"…

蔚来李斌卖手机:安卓系统,苹果售价,一年一发

‍作者 | Amy 编辑 | 德新 车圈大佬的玩法真让人寻不着套路&#xff01; 苹果的库克和小米的雷布斯&#xff0c;甚至是FF贾老板准备许久&#xff0c;都想分一块新能源车的蛋糕&#xff0c;蔚来李斌却反手进军手机界&#xff0c;从宣布造手机到手机入网仅仅隔了一年。 近期&a…

CentOS下载ISO镜像的方法

目录 一、CentOS 介绍 二、进入CentOS 官方网站 三、步骤 一、CentOS 介绍 CentOS&#xff0c;中文意思是社区企业操作系统是Linux发行版之一&#xff0c;是免费的、开源的、可以重新分发的开源操作系统。 CentOS Linux发行版是一个稳定的&#xff0c;可预测的&#xff0…

【旅游度假】Axure酒店在线预订APP原型图 旅游度假子模块原型模板

作品概况 页面数量&#xff1a;共 10 页 兼容软件&#xff1a;Axure RP 9/10&#xff0c;不支持低版本 应用领域&#xff1a;旅游度假&#xff0c;生活服务 作品申明&#xff1a;页面内容仅用于功能演示&#xff0c;无实际功能 作品特色 本作品为「酒店在线预订」的移动端…

基于5G边缘网关的储能在线监测方案

近年以来&#xff0c;光伏、风力、水力发电等产业发展迅速&#xff0c;新能源在电力市场的占比持续增加&#xff0c;已经成为电力系统的重要组成部分。但由于光伏、风力、水力等发电方式存在天然的波动性&#xff0c;因此也需要配套储能、蓄能系统&#xff0c;保障新能源运行和…

JCTools Mpsc源码详解(一)

Jctools介绍--jctools是一个Java开源并发非阻塞数据结构实现,其中主要实现了非阻塞Map和非阻塞queue,旨在为Java提供高性能并发数据结构实现; jctool的特点--为什么性能高: lazyset--putOrderedObject,使用loadload内存屏障,写不会立即可见大量的位运算伪共享-通过pad类实现内…

连接pgsql数据库 sslmode sslrootcert sslkey sslcert 参数的作用

sslmode 参数的作用 sslmode 参数用于指定数据库连接时使用的 SSL 加密模式。SSL&#xff08;Secure Sockets Layer&#xff09;是一种加密协议&#xff0c;用于保护数据在客户端和服务器之间的传输过程&#xff0c;以增加数据传输的安全性。sslmode 参数可以设置不同的值&…

Elasticsearch 查询之Function Score Query

前言 ES 的主查询评分模式分为两种&#xff0c;是信息检索领域的重要算法&#xff1a; TF-IDF 算法 和 BM25 算法。 Elasticsearch 从版本 5.0 开始引入了 BM25 算法作为默认的文档评分&#xff08;relevance scoring&#xff09;算法。在此之前&#xff0c;Elasticsearch 使…

【Django】Task3 外键的使用、Queryset和Instance

【Django】Task3 外键的使用、Queryset和Instance Task3主要理解数据库外键的使用场景&#xff0c;了解Queryset的功能&#xff0c;通过编写代码体验Queryset中对数据库实例的curd操作&#xff0c;同时了解到Instance的定义。 1.外键的使用 1.1什么是外键 数据表外键是数据…

(二)结构型模式:7、享元模式(Flyweight Pattern)(C++实例)

目录 1、享元模式&#xff08;Flyweight Pattern&#xff09;含义 2、享元模式的UML图学习 3、享元模式的应用场景 4、享元模式的优缺点 5、C实现享元模式的简单实例 1、享元模式&#xff08;Flyweight Pattern&#xff09;含义 享元模式&#xff08;Flyweight&#xff09…

redis基本介绍以及在node中使用

文章目录 引言一、什么是redis1. redis简介2. redis的特点3. redis的应用场景 二、redis在windows下安装1. 下载安装2.验证是否安装成功3. 配置环境变量 三、redis-cli常用命令介绍1. redis-cli2. keys *3. set key value4. get key5. exists key6. del key7. info8. flushdb9.…

安装svn插件集成myeclipse2014

第一种&#xff1a; 直接借助myeclipse2014自己的help&#xff0c;当然外网这比较慢了&#xff0c;但是能解决问题的办法就是好办法&#xff0c;能更有效的就是更好的办法&#xff0c;得留着啊。 1.打开myeclipse的help---install from site http://subclipse.tigris.org/upd…

Android设置顶部状态栏颜色

Android设置顶部状态栏颜色_wx637304bacd051的技术博客_51CTO博客

在自定义数据集上使用 Detectron2 和 PyTorch 进行人脸检测

本文讲讲述如何使用Python在自定义人脸检测数据集上微调预训练的目标检测模型。学习如何为Detectron2和PyTorch准备自定义人脸检测数据集&#xff0c;微调预训练模型以在图像中找到人脸边界。 人脸检测是在图像中找到&#xff08;边界的&#xff09;人脸的任务。这在以下情况下…

【第16例】IPD开发流程:横向管理工具之袖珍卡

目录 前言 袖珍卡 作者介绍 相关课程 前言 IPD 本身是一个非常庞杂的体系&#xff0c;几乎涵盖了企业的方方面面。 不仅仅是华为&#xff0c;包括一些引入 IPD 的新星科技企业。 他们对 IPD 的引入也是走了先僵化再优化的一个过程。 比如说开始的阶段全盘照抄走流程&…

vue3新建的项目如何配置

如何创建vue项目链接&#xff1a;http://t.csdn.cn/tX8wY 点击src删除一些没有用的东西 首先查看node_modules文件夹有没有pnpm文件夹&#xff0c;有的话删除node_modules文件夹 重新使用npm i进行安装 在APP.vue下面删除无用代码 删除前 删除后 在views下面找到Home首页删…

androidstudio Please specify a signing configuration for this variant (release)

当直接运行release版本时&#xff0c;报错Error: The apk for your currently selected variant cannot be signed. Please specify a signing configuration for this variant (package64-release). 解决报错&#xff1a;添加签名&#xff0c;signingConfigs 写在buildTypes前…

ffmpeg合并mp4视频文件

下载ffmpeg Download FFmpeg 2配置环境 右键此电脑-》属性-》高级系统设置 环境变量-》path 解压上面ffmpeg压缩包&#xff0c;找到bin目录&#xff0c;复制完整路径&#xff0c;添加到path环境变量中 测试ffmpeg ffmpeg合并MP4文件 创建一个文本文件&#xff0c;例如inpu…

C# 使用递归方法实现汉诺塔步数计算

C# 使用递归方法实现汉诺塔步数计算 Part 1 什么是递归Part 2 汉诺塔Part 3 程序 Part 1 什么是递归 举一个例子&#xff1a;计算从 1 到 x 的总和 public int SumFrom1ToX(int x) {if(x 1){return 1;}else{int result x SumFrom1ToX_2(x - 1); // 调用自己return result…