如何使用mpb库创建两行式进度条及多进度条实时更新?
用mpb实现两行式多进度条
核心实现思路
利用mpb的自定义装饰器,为每个进度条绑定动态更新的状态行(单独占一行),下方紧跟进度条。通过线程安全的状态结构体管理任务信息,搭配高刷新率配置实现实时更新。
完整代码示例
package main import ( "fmt" "path/filepath" "sync" "time" "github.com/vbauerster/mpb/v8" "github.com/vbauerster/mpb/v8/decor" ) // TaskStatus 管理单个任务的状态信息,保证线程安全 type TaskStatus struct { mu sync.Mutex filename string mode string pass string done bool } // String 返回格式化后的状态行文本 func (ts *TaskStatus) String() string { ts.mu.Lock() defer ts.mu.Unlock() var status string if ts.done { status = fmt.Sprintf("Processing DONE [Mode: %s]", ts.mode) } else { status = fmt.Sprintf("Processing %s ...", ts.filename) if ts.mode != "" { status += fmt.Sprintf(" [Mode: %s]", ts.mode) } if ts.pass != "" { status += fmt.Sprintf(" [Pass: %s]", ts.pass) } } return status } // Update 更新任务状态 func (ts *TaskStatus) Update(filename, mode, pass string, done bool) { ts.mu.Lock() defer ts.mu.Unlock() ts.filename = filename ts.mode = mode ts.pass = pass ts.done = done } func main() { // 待处理文件列表 list := []string{ "C:\\Temp\\01.png", "C:\\Temp\\02.png", "C:\\Temp\\03.png", "C:\\Temp\\test.png", "C:\\Temp\\test01.png", } totalTasks := len(list) // 初始化mpb,设置高刷新率保证实时更新 p := mpb.New(mpb.WithRefreshRate(10 * time.Millisecond)) var wg sync.WaitGroup wg.Add(totalTasks) for idx, filePath := range list { filename := filepath.Base(filePath) status := &TaskStatus{} // 初始状态:处理当前文件,模式WebP status.Update(filename, "WebP", "", false) // 创建进度条:总步数为任务总数,每行分为状态行+进度条 bar := p.AddBar(int64(totalTasks), mpb.PrependDecorators( // 自定义装饰器:输出状态行并换行 decor.Func(func(s decor.Statistics) string { return status.String() + "\n" }), // 进度计数:当前完成数/总任务数 decor.CountersNoUnit("%d / %d", decor.WCSyncWidth), ), mpb.AppendDecorators( // 进度条样式 decor.Percentage(decor.WCSyncWidth), decor.ETA(decor.ET_STYLE_GO), ), // 设置进度条宽度 mpb.BarWidth(25), ) // 模拟任务处理协程 go func(taskIdx int, b *mpb.Bar, ts *TaskStatus) { defer wg.Done() // 模拟第一次处理耗时 time.Sleep(1500 * time.Millisecond) // 完成一个任务,进度+1 b.Increment() // 模拟重复处理同一文件(仅第一个任务) if taskIdx == 0 { // 更新状态:切换为WebM模式,第一次pass ts.Update("01.mp4", "WebM", "1/2", false) time.Sleep(1500 * time.Millisecond) // 更新状态:第二次pass,进度保持不变 ts.Update("01.mp4", "WebM", "2/2", false) time.Sleep(1500 * time.Millisecond) } // 标记任务完成 ts.Update(filename, "WebP", "", true) // 等待状态刷新后结束 time.Sleep(100 * time.Millisecond) }(idx, bar, status) } // 等待所有任务完成 wg.Wait() // 等待mpb输出结束 p.Wait() }
关键特性说明
- 动态状态行:通过
TaskStatus结构体管理任务信息,自定义装饰器实时渲染状态行,支持添加模式、处理次数等额外信息。 - 重复处理无进度变化:重复处理同一文件时,仅更新状态文本,不调用
Increment(),进度条保持当前进度。 - 实时多进度条:设置
WithRefreshRate(10*time.Millisecond)保证状态变化后立即刷新,多个进度条独立更新互不干扰。 - 线程安全:
TaskStatus使用互斥锁保证多协程下的状态更新安全。
内容的提问来源于stack exchange,提问作者tetratheta
相关产品推荐
相关产品推荐

