项目概述

在这里插入图片描述

在这里插入图片描述

项目背景

PK进度条是一种特殊的进度展示组件,常用于对比场景,如投票、PK对战等。它通过左右两个不同颜色的区域来展示双方的进度比例,并在各自区域内显示对应的文字标签。本项目基于Qt/QML框架,实现了一个功能完整的PK进度条组件,支持动态进度更新、自定义颜色和文字,为HarmonyOS应用提供直观的对比展示方案。

组件特性

本项目实现的PK进度条组件具有以下特性:

  • 双色对比:左右两个不同颜色的区域,清晰展示对比关系
  • 动态比例:根据进度值动态调整左右区域的比例
  • 文字标签:左右区域各自显示对应的文字标签
  • 无缝衔接:左右区域无缝衔接,无间隙或重叠
  • 响应式设计:支持不同尺寸,自适应布局

技术栈选择

前端框架:Qt/QML

选择理由:

  1. Rectangle组件:QML的Rectangle组件可以方便地实现左右两个区域
  2. Anchors布局:使用anchors实现精确的布局和对齐
  3. 属性绑定:使用属性绑定实现动态响应
  4. 简洁实现:相比Canvas绘制,使用Rectangle更简洁高效

核心技术点

  • QtQuick 2.15:UI框架
  • Rectangle:基础形状组件
  • Anchors:布局系统
  • Text:文字显示
  • 属性绑定:响应式更新

组件设计

整体架构

PK进度条组件的架构设计:

Item (root)
├── Rectangle (leftBar) - 左侧进度条
│   └── Text - 左侧文字标签
└── Rectangle (rightBar) - 右侧进度条
    └── Text - 右侧文字标签

核心属性

property real value: 0              // 当前值(左侧进度)
property real minimum: 0            // 最小值
property real maximum: 100           // 最大值
property real progress: ...         // 计算得出的进度比例(0-1)

// 颜色配置
property color leftColor: "#2B4AFF"  // 左侧颜色(蓝色)
property color rightColor: "#FF0000"  // 右侧颜色(红色)

// 文字配置
property string leftText: "十三先生"  // 左侧文字
property string rightText: "对手"     // 右侧文字

核心功能实现

1. 进度值计算

使用标准的进度计算方式:

property real progress: Math.max(0, Math.min(1, (value - minimum) / (maximum - minimum)))

确保进度值始终在0-1范围内。

2. 左侧进度条(leftBar)

左侧进度条占据左侧部分,宽度根据进度值计算:

Rectangle {
    id: leftBar
    anchors.left: parent.left
    anchors.top: parent.top
    anchors.bottom: parent.bottom
    width: parent.width * progress  // 宽度 = 父容器宽度 × 进度比例
    color: leftColor
    
    Text {
        anchors.left: parent.left
        anchors.leftMargin: 20
        anchors.verticalCenter: parent.verticalCenter
        text: leftText
        color: "white"
        font.pixelSize: 12
    }
}

关键技术点:

  • width: parent.width * progress:宽度根据进度比例动态计算
  • anchors.left: parent.left:左对齐
  • 文字使用anchors.leftleftMargin: 20固定在左侧固定位置

3. 右侧进度条(rightBar)

右侧进度条占据剩余部分:

Rectangle {
    id: rightBar
    anchors.left: leftBar.right      // 紧贴左侧进度条右侧
    anchors.top: parent.top
    anchors.bottom: parent.bottom
    anchors.right: parent.right      // 右对齐
    color: rightColor
    
    Text {
        anchors.left: parent.left    // 固定在右侧进度条的左侧
        anchors.leftMargin: 20       // 与左侧文字相同的边距
        anchors.verticalCenter: parent.verticalCenter
        text: rightText
        color: "white"
        font.pixelSize: 12
    }
}

关键技术点:

  • anchors.left: leftBar.right:紧贴左侧进度条,确保无缝衔接
  • anchors.right: parent.right:右对齐,占据剩余空间
  • 文字使用anchors.left固定在右侧进度条的左侧固定位置,而不是固定在右侧边缘

为什么文字固定在左侧?

  • 当右侧进度条很窄时(如进度值很高),如果文字固定在右侧边缘,可能看不到或被截断
  • 固定在左侧可以确保文字始终显示在进度条内部,即使进度条很窄也能看到

4. 无缝衔接

左右两个进度条通过anchors实现无缝衔接:

// 左侧进度条
Rectangle {
    id: leftBar
    anchors.left: parent.left
    width: parent.width * progress
}

// 右侧进度条
Rectangle {
    id: rightBar
    anchors.left: leftBar.right  // 关键:紧贴左侧进度条
    anchors.right: parent.right
}

说明:

  • anchors.left: leftBar.right确保右侧进度条紧贴左侧进度条
  • 没有间隙,也没有重叠
  • 总宽度始终等于parent.width

文字定位策略

问题分析

在PK进度条中,文字定位是一个关键问题:

  1. 左侧文字:固定在左侧进度条的左侧,这是合理的
  2. 右侧文字:如果固定在右侧进度条的右侧边缘,当进度值很高时,右侧进度条会很窄,文字可能看不到或被截断

解决方案

将右侧文字也固定在右侧进度条的左侧(与左侧文字对称):

Text {
    anchors.left: parent.left      // 固定在右侧进度条的左侧
    anchors.leftMargin: 20         // 与左侧文字相同的边距
    anchors.verticalCenter: parent.verticalCenter
    text: rightText
    color: "white"
    font.pixelSize: 12
}

优势:

  • 文字始终显示在进度条内部
  • 即使右侧进度条很窄,文字也能看到
  • 左右文字位置对称,视觉效果统一

对比方案

方案1:固定在右侧边缘(不推荐)

Text {
    anchors.right: parent.right
    anchors.rightMargin: 20
    // 问题:当右侧进度条很窄时,文字可能看不到
}

方案2:固定在左侧(推荐)

Text {
    anchors.left: parent.left
    anchors.leftMargin: 20
    // 优势:文字始终在进度条内部,即使很窄也能看到
}

开发要点与技巧

1. 精确的布局计算

左侧进度条宽度:

width: parent.width * progress

右侧进度条宽度:

// 不需要显式设置width,使用anchors自动计算
anchors.left: leftBar.right
anchors.right: parent.right

说明:

  • 左侧宽度明确计算
  • 右侧使用anchors自动占据剩余空间
  • 确保总宽度等于parent.width

2. 文字边距统一

左右文字使用相同的边距:

// 左侧文字
anchors.leftMargin: 20

// 右侧文字
anchors.leftMargin: 20  // 相同的边距

说明:

  • 统一的边距确保视觉效果一致
  • 可以根据需要调整边距值

3. 颜色对比

使用对比鲜明的颜色:

property color leftColor: "#2B4AFF"   // 蓝色
property color rightColor: "#FF0000"  // 红色

说明:

  • 蓝色和红色形成强烈对比
  • 可以根据应用主题自定义颜色

4. 文字颜色

文字使用白色,确保在各种背景下都清晰可见:

color: "white"

说明:

  • 白色文字在蓝色和红色背景上都清晰可见
  • 如果背景色较浅,可以改为深色文字

5. 响应式设计

组件响应尺寸变化:

// 宽度自动响应parent.width变化
width: parent.width * progress

// 高度自动响应parent.height变化
anchors.top: parent.top
anchors.bottom: parent.bottom

说明:

  • 使用anchors实现响应式布局
  • 自动适配不同尺寸的容器

使用示例

基本使用

import QtQuick 2.15

PKProgressBar {
    width: 400
    height: 50
    value: 50
    maximum: 100
    leftText: "选项A"
    rightText: "选项B"
}

动态更新进度

Item {
    property real pkValue: 0
    
    Timer {
        interval: 100
        running: true
        repeat: true
        onTriggered: {
            pkValue += 1
            if (pkValue > 100) pkValue = 0
        }
    }
    
    PKProgressBar {
        width: 400
        height: 50
        value: pkValue
        maximum: 100
        leftText: "玩家A"
        rightText: "玩家B"
    }
}

自定义颜色和文字

PKProgressBar {
    width: 400
    height: 50
    value: 60
    maximum: 100
    
    // 自定义颜色
    leftColor: "#4CAF50"   // 绿色
    rightColor: "#F44336"  // 红色
    
    // 自定义文字
    leftText: "支持"
    rightText: "反对"
}

投票场景示例

Item {
    property real voteFor: 65
    property real voteAgainst: 35
    
    PKProgressBar {
        width: 400
        height: 50
        value: voteFor
        maximum: voteFor + voteAgainst
        leftText: "支持:" + voteFor + "票"
        rightText: "反对:" + voteAgainst + "票"
    }
}

PK对战场景示例

Item {
    property real player1Score: 75
    property real player2Score: 25
    
    PKProgressBar {
        width: 400
        height: 50
        value: player1Score
        maximum: player1Score + player2Score
        leftText: "玩家1:" + player1Score + "分"
        rightText: "玩家2:" + player2Score + "分"
        leftColor: "#2196F3"   // 蓝色
        rightColor: "#FF9800"  // 橙色
    }
}

总结与展望

技术总结

本项目成功实现了功能完整的PK进度条组件,展示了Qt/QML在HarmonyOS平台上的强大能力:

  1. 双区域设计:通过两个Rectangle实现左右对比区域
  2. 精确布局:使用anchors实现无缝衔接和响应式布局
  3. 文字定位:巧妙的文字定位策略,确保在各种情况下都能正确显示
  4. 简洁高效:相比Canvas绘制,使用Rectangle更简洁高效

扩展方向

  1. 动画过渡:可以添加进度变化的动画过渡效果
  2. 更多样式:可以添加圆角、阴影等视觉效果
  3. 交互功能:可以添加点击交互,允许用户投票或选择
  4. 多区域支持:可以扩展为支持多个区域的对比展示

最佳实践

  1. 使用anchors布局:使用anchors实现精确的布局和对齐
  2. 文字定位策略:将文字固定在进度条内部,而不是边缘
  3. 颜色对比:使用对比鲜明的颜色,增强视觉效果
  4. 响应式设计:确保组件在不同尺寸下都能正确显示

常见问题

Q: 为什么右侧文字不固定在右侧边缘?

A: 当进度值很高时,右侧进度条会很窄,如果文字固定在右侧边缘,可能看不到或被截断。固定在左侧可以确保文字始终显示在进度条内部。

Q: 如何实现左右区域的平滑过渡?

A: 可以使用Behavior实现属性变化的动画过渡:

Behavior on value {
    NumberAnimation {
        duration: 300
        easing.type: Easing.OutQuad
    }
}

Q: 如何自定义左右区域的比例?

A: 通过valuemaximum属性控制比例。例如,value: 60, maximum: 100表示左侧占60%,右侧占40%。


相关资源

  • 项目地址:https://gitcode.com/szkygc/HarmonyOs_PC-PGC/tree/main/progress
  • Qt官方文档:https://doc.qt.io/qt-5/qtquick-index.html
  • QML Rectangle文档:https://doc.qt.io/qt-5/qml-qtquick-rectangle.html
  • QML Anchors文档:https://doc.qt.io/qt-5/qml-qtquick-item.html#anchors-prop
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐