golang终端应用多进度条显示插件库mpb的使用
golang终端应用多进度条显示插件库mpb的使用
简介
mpb是一个用于在终端应用程序中渲染进度条的Go库。
主要特性
- 多进度条支持:支持多个进度条同时显示
- 动态总数:可以在进度条运行时设置总数
- 动态添加/移除:可以动态添加或移除进度条
- 取消功能:可以取消整个渲染过程
- 预定义装饰器:包括已用时间、基于EWMA的ETA、百分比、字节计数器等
- 装饰器宽度同步:在多个进度条之间同步装饰器的宽度
使用示例
渲染单个进度条
package main
import (
"math/rand"
"time"
"github.com/vbauerster/mpb/v8"
"github.com/vbauerster/mpb/v8/decor"
)
func main() {
// 初始化进度容器,自定义宽度
p := mpb.New(mpb.WithWidth(64))
total := 100
name := "Single Bar:"
// 创建单个进度条,将继承容器的宽度
bar := p.New(int64(total),
// 自定义样式的BarFillerBuilder
mpb.BarStyle().Lbound("╢").Filler("▌").Tip("▌").Padding("░").Rbound("╟"),
mpb.PrependDecorators(
// 在右侧显示名称和一个空格
decor.Name(name, decor.WC{C: decor.DindentRight | decor.DextraSpace}),
// 在完成时用"done"消息替换ETA装饰器
decor.OnComplete(decor.AverageETA(decor.ET_STYLE_GO), "done"),
),
mpb.AppendDecorators(decor.Percentage()),
)
// 模拟工作
max := 100 * time.Millisecond
for i := 0; i < total; i++ {
time.Sleep(time.Duration(rand.Intn(10)+1) * max / 10)
bar.Increment()
}
// 等待进度条完成并刷新
p.Wait()
}
渲染多个进度条
package main
import (
"fmt"
"math/rand"
"sync"
"time"
"github.com/vbauerster/mpb/v8"
"github.com/vbauerster/mpb/v8/decor"
)
func main() {
var wg sync.WaitGroup
// 传入的wg将在p.Wait()调用时被计算
p := mpb.New(mpb.WithWaitGroup(&wg))
total, numBars := 100, 3
wg.Add(numBars)
for i := 0; i < numBars; i++ {
name := fmt.Sprintf("Bar#%d:", i)
bar := p.AddBar(int64(total),
mpb.PrependDecorators(
// 简单的名称装饰器
decor.Name(name),
// decor.DSyncWidth位启用列宽同步
decor.Percentage(decor.WCSyncSpace),
),
mpb.AppendDecorators(
// 在完成时用"done"消息替换ETA装饰器
decor.OnComplete(
// EWMA年龄为30的ETA装饰器
decor.EwmaETA(decor.ET_STYLE_GO, 30, decor.WCSyncWidth), "done",
),
),
)
// 模拟工作
go func() {
defer wg.Done()
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
max := 100 * time.Millisecond
for i := 0; i < total; i++ {
// start变量仅用于EWMA计算
// EWMA的度量单位是迭代的持续时间
start := time.Now()
time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10)
// 需要调用EwmaIncrement来满足ewma装饰器的约定
bar.EwmaIncrement(time.Since(start))
}
}()
}
// 等待传入的wg和所有进度条完成并刷新
p.Wait()
}
动态总数示例
复杂示例
IO示例
更多关于golang终端应用多进度条显示插件库mpb的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang终端应用多进度条显示插件库mpb的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用mpb库实现Golang终端多进度条显示
mpb (Multi Progress Bar) 是一个优秀的Golang库,用于在终端应用程序中显示多个进度条。下面我将详细介绍如何使用mpb库。
安装mpb
首先安装mpb库:
go get github.com/vbauerster/mpb/v8
基本使用示例
package main
import (
"math/rand"
"time"
"github.com/vbauerster/mpb/v8"
"github.com/vbauerster/mpb/v8/decor"
)
func main() {
// 创建进度条容器
p := mpb.New(
mpb.WithWidth(60), // 设置进度条宽度
// 添加3个进度条
for i := 0; i < 3; i++ {
name := "进度条 " + string('A'+i)
// 创建一个新的进度条
bar := p.AddBar(100,
mpb.PrependDecorators(
// 显示名称
decor.Name(name, decor.WC{W: len(name) + 1, C: decor.DidentRight}),
// 显示百分比
decor.Percentage(decor.WCSyncSpace),
),
mpb.AppendDecorators(
// 显示预计剩余时间
decor.EwmaETA(decor.ET_STYLE_GO, 60),
),
)
// 模拟任务进度
go func() {
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
max := 100 * time.Millisecond
for !bar.Completed() {
time.Sleep(time.Duration(rng.Intn(10)+1) * max / 10)
bar.Increment()
}
}()
}
// 等待所有进度条完成
p.Wait()
}
高级功能
1. 自定义进度条样式
bar := p.AddBar(100,
mpb.BarStyle("[=>-|"),
mpb.BarFillerClearOnComplete(),
mpb.PrependDecorators(
decor.Name("自定义样式: "),
decor.CountersNoUnit("%d / %d"),
),
)
2. 动态添加进度条
p := mpb.New()
// 主循环中动态添加进度条
for i := 0; i < 5; i++ {
time.Sleep(500 * time.Millisecond)
name := fmt.Sprintf("动态进度条 #%d:", i+1)
bar := p.AddBar(100,
mpb.PrependDecorators(
decor.Name(name),
decor.Percentage(),
),
)
go func(b *mpb.Bar) {
for !b.Completed() {
time.Sleep(100 * time.Millisecond)
b.IncrBy(rand.Intn(5) + 1)
}
}(bar)
}
p.Wait()
3. 复杂进度条组合
p := mpb.New()
// 主进度条
mainBar := p.AddBar(100,
mpb.PrependDecorators(
decor.Name("主任务:"),
decor.Percentage(),
),
mpb.AppendDecorators(
decor.OnComplete(
decor.EwmaETA(decor.ET_STYLE_GO, 60), "完成",
),
),
)
// 子任务进度条组
subBars := make([]*mpb.Bar, 3)
for i := range subBars {
subBars[i] = p.AddBar(100,
mpb.BarQueueAfter(mainBar), // 在主进度条之后显示
mpb.BarFillerClearOnComplete(),
mpb.PrependDecorators(
decor.Name(fmt.Sprintf(" 子任务%d:", i+1)),
decor.CountersNoUnit("%d / %d"),
),
)
}
// 模拟任务执行
go func() {
for i := 0; i < 100; i++ {
mainBar.Increment()
time.Sleep(50 * time.Millisecond)
// 每20%更新一次子任务
if i%20 == 0 {
for _, b := range subBars {
b.SetCurrent(0)
go func(bar *mpb.Bar) {
for !bar.Completed() {
time.Sleep(100 * time.Millisecond)
bar.IncrBy(rand.Intn(10) + 1)
}
}(b)
}
}
}
}()
p.Wait()
注意事项
- 确保在程序退出前调用
p.Wait()
,否则可能看不到完整的进度条 - 进度条的宽度应考虑终端窗口大小
- 对于大量进度条,可以使用
mpb.WithRefreshRate
调整刷新频率 - 可以使用
decor.OnComplete
在进度条完成后显示自定义消息
mpb库功能强大,支持多种自定义选项,以上示例展示了基本用法和一些高级特性。根据实际需求,您可以进一步探索其文档以了解更多功能。