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


项目背景
PK进度条是一种特殊的进度展示组件,常用于对比场景,如投票、PK对战等。它通过左右两个不同颜色的区域来展示双方的进度比例,并在各自区域内显示对应的文字标签。本项目基于Qt/QML框架,实现了一个功能完整的PK进度条组件,支持动态进度更新、自定义颜色和文字,为HarmonyOS应用提供直观的对比展示方案。
组件特性
本项目实现的PK进度条组件具有以下特性:
- ✅ 双色对比:左右两个不同颜色的区域,清晰展示对比关系
- ✅ 动态比例:根据进度值动态调整左右区域的比例
- ✅ 文字标签:左右区域各自显示对应的文字标签
- ✅ 无缝衔接:左右区域无缝衔接,无间隙或重叠
- ✅ 响应式设计:支持不同尺寸,自适应布局
技术栈选择
前端框架:Qt/QML
选择理由:
- Rectangle组件:QML的Rectangle组件可以方便地实现左右两个区域
- Anchors布局:使用anchors实现精确的布局和对齐
- 属性绑定:使用属性绑定实现动态响应
- 简洁实现:相比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.left和leftMargin: 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进度条中,文字定位是一个关键问题:
- 左侧文字:固定在左侧进度条的左侧,这是合理的
- 右侧文字:如果固定在右侧进度条的右侧边缘,当进度值很高时,右侧进度条会很窄,文字可能看不到或被截断
解决方案
将右侧文字也固定在右侧进度条的左侧(与左侧文字对称):
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平台上的强大能力:
- 双区域设计:通过两个Rectangle实现左右对比区域
- 精确布局:使用anchors实现无缝衔接和响应式布局
- 文字定位:巧妙的文字定位策略,确保在各种情况下都能正确显示
- 简洁高效:相比Canvas绘制,使用Rectangle更简洁高效
扩展方向
- 动画过渡:可以添加进度变化的动画过渡效果
- 更多样式:可以添加圆角、阴影等视觉效果
- 交互功能:可以添加点击交互,允许用户投票或选择
- 多区域支持:可以扩展为支持多个区域的对比展示
最佳实践
- 使用anchors布局:使用anchors实现精确的布局和对齐
- 文字定位策略:将文字固定在进度条内部,而不是边缘
- 颜色对比:使用对比鲜明的颜色,增强视觉效果
- 响应式设计:确保组件在不同尺寸下都能正确显示
常见问题
Q: 为什么右侧文字不固定在右侧边缘?
A: 当进度值很高时,右侧进度条会很窄,如果文字固定在右侧边缘,可能看不到或被截断。固定在左侧可以确保文字始终显示在进度条内部。
Q: 如何实现左右区域的平滑过渡?
A: 可以使用Behavior实现属性变化的动画过渡:
Behavior on value {
NumberAnimation {
duration: 300
easing.type: Easing.OutQuad
}
}
Q: 如何自定义左右区域的比例?
A: 通过value和maximum属性控制比例。例如,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
更多推荐



所有评论(0)