QML ProgressBar控件详解

在 QML 中,ProgressBar 是一个常用的进度条控件,用于显示任务的完成进度。以下是 ProgressBar 的详细用法,包括基本用法、自定义样式、动态绑定数据等。


1. 基本用法

1.1 最简单的 ProgressBar

qml 复制代码
import QtQuick.Controls 2.15

ProgressBar {
    width: 200
    height: 20
    from: 0    // 最小值
    to: 100    // 最大值
    value: 50  // 当前值(0~100)
}
  • from:最小值(默认 0)。
  • to:最大值(默认 1)。
  • value:当前进度值(范围 [from, to])。

1.2 绑定动态数据

qml 复制代码
ProgressBar {
    value: slider.value  // 绑定 Slider 的值
    from: 0
    to: 100
}

Slider {
    id: slider
    from: 0
    to: 100
    value: 30
}

这样 ProgressBar 会随着 Slider 的变化而更新。


2. 自定义样式

ProgressBar 主要由两个部分组成:

  1. background:背景样式。
  2. contentItem:进度条填充部分。

2.1 修改背景和进度条颜色

qml 复制代码
ProgressBar {
    value: 75
    from: 0
    to: 100

    // 背景样式
    background: Rectangle {
        implicitWidth: 200
        implicitHeight: 20
        color: "#e0e0e0"  // 背景色
        radius: 5         // 圆角
    }

    // 进度条填充部分
    contentItem: Rectangle {
        width: parent.visualPosition * parent.width  // 计算宽度
        height: parent.height
        radius: 5
        color: "#4CAF50"  // 进度条颜色
    }
}
  • visualPosition:value 的归一化值((value - from) / (to - from))。

2.2 添加文字显示进度百分比

qml 复制代码
ProgressBar {
    id: progressBar
    value: 75
    from: 0
    to: 100

    background: Rectangle {
        color: "#e0e0e0"
        radius: 5
    }

    contentItem: Item {
        Rectangle {
            width: parent.visualPosition * parent.width
            height: parent.height
            radius: 5
            color: "#4CAF50"
        }

        // 显示进度百分比
        Text {
            anchors.centerIn: parent
            text: Math.round(progressBar.value) + "%"
            color: "white"
            font.bold: true
        }
    }
}

3. 动态数据绑定(结合 ListView 或 Model)

3.1 在 ListView 中使用 ProgressBar

qml 复制代码
ListView {
    width: 300
    height: 200
    model: ListModel {
        ListElement { name: "CPU"; value: 60 }
        ListElement { name: "RAM"; value: 80 }
        ListElement { name: "GPU"; value: 40 }
    }

    delegate: Row {
        spacing: 10
        width: parent.width

        Text {
            text: name
            width: 50
        }

        ProgressBar {
            width: 200
            value: model.value
            from: 0
            to: 100

            contentItem: Rectangle {
                width: parent.visualPosition * parent.width
                height: parent.height
                color: value < 50 ? "#4CAF50" : (value < 80 ? "#FFC107" : "#F44336")
            }
        }
    }
}
  • 根据 value 不同,进度条颜色变化(绿色→黄色→红色)。

3.2 结合 C++ 数据模型

如果数据来自 C++(如 QAbstractListModel),确保:

  1. value 是动态绑定的 (Q_PROPERTY + NOTIFY 信号)。
  2. ListView 的 cacheBuffer 足够大,避免滚动时数据丢失。
cpp 复制代码
// C++ Model
class ResourceModel : public QAbstractListModel {
    Q_OBJECT
    Q_PROPERTY(int cpuUsage READ cpuUsage NOTIFY cpuUsageChanged)
    // ...
};
qml 复制代码
// QML
ListView {
    model: resourceModel
    delegate: ProgressBar {
        value: model.cpuUsage
        from: 0
        to: 100
    }
}

4. 常见问题

4.1 进度问题

  • 确保 value 是动态绑定的(model)。
  • visualPosition 在滚动后没有正确更新的问题。在 QML 中,当使用 ListView 和自定义进度条时,有时会出现渲染问题,特别是在滚动后。
  • 确保 ListView 有足够的缓存。
qml 复制代码
ListView {
    // ...
    cacheBuffer: 2000 // 根据需要调整这个值
    //强制 contentItem 重新计算宽度
    ProgressBar {
    id: progressBar
    value: System_cpu_percent
    from: 0
    to: 100
    onValueChanged: {
        contentItem.width = (value / to) * width;
    }
    // ...
}
}

4.2 如何让进度条动画更平滑?

qml 复制代码
contentItem: Rectangle {
    width: parent.visualPosition * parent.width
    Behavior on width { NumberAnimation { duration: 200 } }  // 200ms 动画
}

5. 完整示例

qml 复制代码
import QtQuick 2.15
import QtQuick.Controls 2.15

ProgressBar {
    id: progressBar
    width: 200
    height: 20
    value: 75
    from: 0
    to: 100

    background: Rectangle {
        implicitWidth: 200
        implicitHeight: 20
        color: "#e0e0e0"
        radius: 5
        border.color: "#999999"
    }

    contentItem: Rectangle {
        width: parent.visualPosition * parent.width
        height: parent.height
        radius: 5
        color: {
            if (progressBar.value < 30) return "#4CAF50";  // 绿色
            else if (progressBar.value < 70) return "#FFC107";  // 黄色
            else return "#F44336";  // 红色
        }

        Behavior on width { NumberAnimation { duration: 200 } }  // 动画效果
    }

    Text {
        anchors.centerIn: parent
        text: Math.round(progressBar.value) + "%"
        color: "white"
        font.bold: true
    }
}

总结

功能 实现方式
基本进度条 ProgressBar { value: 50; from: 0; to: 100 }
自定义样式 修改 background 和 contentItem
动态绑定 value: model.value 或 value: slider.value
动画效果 Behavior on width { NumberAnimation }
相关推荐
一次旅行19 分钟前
DeepSeek‑V4.1‑Flash‑1017完整解读:模型升级+Search/Fetch搜索API开放,Agent开发者要注意哪些坑
前端·网络·人工智能
原则猫9 小时前
UDP 到底怎么实现可靠的
前端
Java后端的Ai之路9 小时前
14、ReactJS - 路由(Router)
前端·react.js·状态模式
裕晟资质规划10 小时前
三类涉密资质延续时限差异分析:军工60日与集成印制3个月的边界
java·服务器·前端·网络·安全
ShineWinsu10 小时前
对于JavaScript:JavaScript基础语法的解析
开发语言·前端·javascript·面试·web·基础语法·循环
月夏10 小时前
Vue3 转 React:18 项对照表 + 5 个必踩的坑(附 7 天上手路线)
前端
广州华水科技11 小时前
单北斗GNSS位移监测系统的应用与维护解析
前端
梦曦i11 小时前
uni-storage 0.1.0 发布:TTL过期管理+多实例隔离
前端·storage·uni-app x
猫头_12 小时前
AI 流式传输工程指南:模型吐出半截 JSON,前端如何边收边渲染?
前端·javascript·llm
console.log('npc')13 小时前
第 1 章 项目概述与环境搭建
前端·人工智能·大模型