qml 电池控件设计(手把手从零开始)

本文介绍了从传统的QWidget框架转向使用QML进行高性能UI开发,特别是如何利用QML的GPU渲染技术创建一个动态显示电量的电池控件,包括代码设计、性能优化以及控件的使用方法。
摘要由CSDN通过智能技术生成

一、说明

做 qt 开发也有好几年了,一直基于QWidget 框架做的开发,使用重写 paint 函数实现各种显示效果,在复杂的 ui 开发中,控件一多或者刷新频率一高,其实也是存在性能限制。
一般来说,qt 的界面对象全部在主线程中运行,main 函数中的 exec()阻塞不断进行事件循环驱动。QWidget的绘制和渲染都是基于 cpu 的,所以这个性能上限吧就感觉相对低点。现在 ui 也是越来越复杂,cpu 压力也就越大。虽然可以通过优化代码提升性能,但是这个浮躁的社会,写起代码来,不得更加浮躁!

然而,qml 居然是使用 gpu 做的渲染,这个是不是就很香了。QWidget 已经n 年没有更新,新的 qt 版本都是围绕 qml 和 3D 做的迭代,感觉 qml 才是qt 的未来。

其实也是断断续续学习过qml,怕年纪越来越大,越不愿意接受新鲜事物,现在还有动力,所以要多做一些学习,并写一些相关的文章记录过程。

之前使用 QWidget 也做过电池控件,有兴趣的朋友可以查看链接:https://blog.csdn.net/weixin_42887343/article/details/113932145

二、效果

在这里插入图片描述

三、需求

  • 最基本的需求就是显示电量了
  • 电量小于 20% 显示橙色,小于 10% 显示红色,否则显示绿色
  • 可以随意设置电池电量
  • 电量变化后,需要有一个渐变的动画
  • 需要显示电池电量百分比文字

四、准备

(1)安装 qtCreator,这个大家应该都没有问题。
(2)使用qtCreator创建 qml 项目,可以参考链接:https://blog.csdn.net/weixin_42887343/article/details/135410332
(3)如果对 qml 不熟悉,可以看一下qml 元素详解:https://blog.csdn.net/weixin_42887343/article/details/135356964

五、代码设计

电池控件的 ui 很简单,可以分成几个部分,电池控件组成结构如下图:

在这里插入图片描述
qml 作为描述性语言,只要使用 qml 对各个部分做一些描述性定义,然后按上图做包含组合即可实现控件。
(0)控件属性定义

    property real batteryLevel: 1       //定义电池电量,0-1
    property real borderWidth: 6        //电池边界宽度
    property color borderColor: "#aaaaaa"   //电池边界线、电池头的颜色
    
    property color nomalLevelColor: "#4CAF50"   //电池电量充足颜色-默认绿色
    property color lowLevelColor: "#FFC107"     //电池电量低-默认橙色
    property color lowerLevelColor: "red"       //电池电量过低-默认红色

(1)电池头

    //电池头
    Rectangle {
        id: batteryHeader
        width: batteryContainer.width / 18
        height: batteryContainer.height / 2.5
        anchors.left:batteryContainer.right
        anchors.verticalCenter: batteryContainer.verticalCenter
        color: borderColor
        radius: 5
        Rectangle {
            x: 0
            y: 0
            width: parent.radius
            height: parent.height
            radius: 0
            color: parent.color
        }
    }

(2)电池电量颜色块

	// 电量rect
    Rectangle {
        id:colorRectiud
        width: (batteryContainer.width - 2 * borderWidth)*(batteryLevel)
        height: batteryContainer.height - 2 * borderWidth
        anchors.verticalCenter: parent.verticalCenter
        x: borderWidth
        color: colorBasedOnValue(batteryLevel)
        radius:5
        // 电量颜色获取函数
        function colorBasedOnValue(value) {
            if (value < 0.1) {
                return root.lowerLevelColor;
            } else if (value < 0.2) {
                return root.lowLevelColor;
            } else {
                return root.nomalLevelColor; // 默认值或其他颜色
            }
        }
    }

(3)电池电量文字

	// 电量文字
	Text {
	    anchors.centerIn: parent
	    text: Math.floor(batteryLevel * 100) + "%"
	    font.pixelSize: 20
	    color: "white"
	}

(4)电池体

// 电池体
    Rectangle {
        id: batteryContainer
        width: parent.width - 2 * borderWidth
        height: parent.height - 2 * borderWidth
        anchors.centerIn: parent
        color: borderColor
        border.color: borderColor // 设置边界线颜色
        border.width: borderWidth // 设置边界线宽度
        radius:10
        // 电量rect
        Rectangle {
        ……(2)
        }
        // 电量文字
        Text {
        ……(3)
        }
    }

(5)电池控件

Rectangle {
    id:root
    property real batteryLevel: 1
    property real borderWidth: 6
    property color borderColor: "#aaaaaa"
    property color nomalLevelColor: "#4CAF50"
    property color lowLevelColor: "#FFC107"
    property color lowerLevelColor: "red"

    width: 200
    height: 100

    // 电池体
    Rectangle {
        ……(4)
    }
    //电池头
    Rectangle {
		……(1)
    }
}

说明

代码中,……(1)表示(1)电池头中对应的代码,……(4)表示第四部分电池体的代码,其他同意思。

从上面代码即可看出,他们的组合关系在代码上即为包含关系

控件的总代码:

// Battery.qml

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.0

Rectangle {
    id:root
    property real batteryLevel: 1
    property real borderWidth: 6
    property color borderColor: "#aaaaaa"
    property color nomalLevelColor: "#4CAF50"
    property color lowLevelColor: "#FFC107"
    property color lowerLevelColor: "red"

    width: 200
    height: 100

    // 电池体
    Rectangle {
        id: batteryContainer
        width: parent.width - 2 * borderWidth
        height: parent.height - 2 * borderWidth
        anchors.centerIn: parent
        color: borderColor
        border.color: borderColor // 设置边界线颜色
        border.width: borderWidth // 设置边界线宽度
        radius:10
        // 电量rect
        Rectangle {
            id:colorRectiud
            width: (batteryContainer.width - 2 * borderWidth)*(batteryLevel)
            height: batteryContainer.height - 2 * borderWidth
            anchors.verticalCenter: parent.verticalCenter
            x: borderWidth
            color: colorBasedOnValue(batteryLevel)
            radius:5
            // 电量颜色获取函数
            function colorBasedOnValue(value) {
                if (value < 0.1) {
                    return root.lowerLevelColor;
                } else if (value < 0.2) {
                    return root.lowLevelColor;
                } else {
                    return root.nomalLevelColor; // 默认值或其他颜色
                }
            }
        }
        // 电量文字
        Text {
            anchors.centerIn: parent
            text: Math.floor(batteryLevel * 100) + "%"
            font.pixelSize: 20
            color: "white"
        }
    }
    //电池头
    Rectangle {
        id: batteryHeader
        width: batteryContainer.width / 18
        height: batteryContainer.height / 2.5
        anchors.left:batteryContainer.right
        anchors.verticalCenter: batteryContainer.verticalCenter
        color: borderColor
        radius: 5
        Rectangle {
            x: 0
            y: 0
            width: parent.radius
            height: parent.height
            radius: 0
            color: parent.color
        }
    }
}

最后, 上面的控件代码需要使用名为 控件名 的 qml 文件包含,如Battery.qml,并将该文件加入资源文件中,入下图所示:

在这里插入图片描述
这样我们就使用 qml实现了一个电池控件。

六、控件使用

(1)在使用中,我们需要定义一个Slider控件,使用它来控制电池电量。(与电池控件平级)
(2)再定义一个鼠标点击区域MouseArea,将点击区域填充为电池,点击后设置鼠标为随机电量。(需要被电池控件包含)
(3)电池还有需要电池渐变变化,所以还需要添加一个动画元素,设置电池当前电量到设置电量的渐变。(需要被电池控件包含)

总代码如下图:

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

Window {
    width: 400
    height: 400
    visible: true
    title: "小小电池控件测试"

    Battery {
        id:batteryID
        anchors.centerIn: parent    //居中于父对象

        PropertyAnimation {         //电量变动动画
            id:batterChange
            target: batteryID
            property: "batteryLevel"
            duration: 500
            easing.type: Easing.InOutQuad
        }
        // 鼠标点击区域
        MouseArea {
            anchors.fill: batteryID
            onClicked: {
                // 模拟电量变化
                batterChange.from=batteryID.batteryLevel    //设置动画初始值
                batterChange.to=Math.random();              //设置动画结束值
                batterChange.start();                       //启动动画
                console.log("batteryLevel changed from "+batterChange.from + " to "+batterChange.to);
            }
        }
    }
    Slider {
        x:batteryID.x
        y:batteryID.y + batteryID.height + 30
        from: 0
        to: 1
        stepSize: 0.01
        value:batteryID.batteryLevel

        onPositionChanged: {
            batteryID.batteryLevel = position;
            console.log("Progress Bar Value:", position);
        }
    }
}

  • 17
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值