golang终端应用进度条渲染插件库uiprogress的使用
Golang终端应用进度条渲染插件库uiprogress的使用
uiprogress是一个用于在终端应用程序中渲染进度条的Go库。它提供了一组灵活的功能和可定制的API。
特性
- 多进度条:可以同时渲染和跟踪多个进度条
- 动态添加:可以随时添加新的进度条,即使进度跟踪已经开始
- 前置和后置功能:可以在进度条前后添加完成百分比和已用时间
- 自定义装饰器函数:可以添加自定义函数和辅助函数来装饰进度条
基本用法
要开始使用进度条,首先调用uiprogress.Start()
,然后使用uiprogress.AddBar(total int)
添加进度条。使用bar.Incr()
或bar.Set(n int)
来更新进度。
package main
import (
"time"
"github.com/gosuri/uiprogress"
)
func main() {
uiprogress.Start() // 开始渲染
bar := uiprogress.AddBar(100) // 添加一个新进度条,总数为100
// 可选:在进度条后添加完成百分比,前面添加已用时间
bar.AppendCompleted()
bar.PrependElapsed()
for bar.Incr() {
time.Sleep(time.Millisecond * 20)
}
}
使用自定义装饰器
除了默认的bar.AppendCompleted()
和bar.PrependElapsed()
装饰器外,你还可以添加自定义装饰器函数。
package main
import (
"time"
"github.com/gosuri/uiprogress"
)
func main() {
var steps = []string{"下载源码", "安装依赖", "编译", "打包", "初始化数据库", "部署", "启动服务"}
bar := uiprogress.AddBar(len(steps))
// 在进度条前添加当前步骤
bar.PrependFunc(func(b *uiprogress.Bar) string {
return "应用: " + steps[b.Current()-1]
})
for bar.Incr() {
time.Sleep(time.Millisecond * 10)
}
}
渲染多个进度条
你可以使用uiprogress.AddBar(n)
添加多个进度条。下面的例子展示了如何并发更新多个进度条,并在流程中后期添加新的进度条。
package main
import (
"sync"
"time"
"github.com/gosuri/uiprogress"
)
func main() {
waitTime := time.Millisecond * 100
uiprogress.Start()
// 在goroutine中启动进度条
var wg sync.WaitGroup
bar1 := uiprogress.AddBar(20).AppendCompleted().PrependElapsed()
wg.Add(1)
go func() {
defer wg.Done()
for bar1.Incr() {
time.Sleep(waitTime)
}
}()
bar2 := uiprogress.AddBar(40).AppendCompleted().PrependElapsed()
wg.Add(1)
go func() {
defer wg.Done()
for bar2.Incr() {
time.Sleep(waitTime)
}
}()
time.Sleep(time.Second)
bar3 := uiprogress.AddBar(20).PrependElapsed().AppendCompleted()
wg.Add(1)
go func() {
defer wg.Done()
for i := 1; i <= bar3.Total; i++ {
bar3.Set(i)
time.Sleep(waitTime)
}
}()
// 等待所有goroutine完成
wg.Wait()
}
使用Incr计数器
Bar.Incr()
是一个原子计数器,可以作为通用跟踪器使用,非常适合跟踪分发到多个goroutine的工作进度。
package main
import (
"fmt"
"math/rand"
"runtime"
"sync"
"time"
"github.com/gosuri/uiprogress"
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) // 使用所有可用的CPU核心
// 创建一个新进度条,并在进度条前添加任务进度,然后分发到1k个goroutine
count := 1000
bar := uiprogress.AddBar(count).AppendCompleted().PrependElapsed()
bar.PrependFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("任务 (%d/%d)", b.Current(), count)
})
uiprogress.Start()
var wg sync.WaitGroup
// 分发到goroutine
for i := 0; i < count; i++ {
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Millisecond * time.Duration(rand.Intn(500)))
bar.Incr()
}()
}
time.Sleep(time.Second) // 等待所有goroutine完成
wg.Wait()
uiprogress.Stop()
}
安装
$ go get -v github.com/gosuri/uiprogress
待办事项
- 通过自动检测窗口尺寸来调整进度条和装饰器大小
- 处理超出垂直屏幕允许范围的更多进度条
许可证
uiprogress基于MIT许可证发布。
更多关于golang终端应用进度条渲染插件库uiprogress的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang终端应用进度条渲染插件库uiprogress的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
uiprogress - Golang终端进度条库使用指南
uiprogress是一个简单易用的Golang终端进度条渲染库,适合在命令行应用中显示任务进度。下面我将详细介绍其使用方法并提供示例代码。
安装
go get github.com/gosuri/uiprogress
基本使用
1. 简单进度条
package main
import (
"time"
"github.com/gosuri/uiprogress"
)
func main() {
uiprogress.Start() // 启动渲染器
bar := uiprogress.AddBar(100) // 添加一个最大值为100的进度条
// 可选:设置进度条格式
bar.AppendCompleted()
bar.PrependElapsed()
for bar.Incr() { // 每次增加1
time.Sleep(time.Millisecond * 20)
}
}
2. 自定义进度条
bar := uiprogress.AddBar(100).
PrependFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("任务(%d/%d)", b.Current(), b.Total)
}).
AppendFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("%.2f%%", b.CompletedPercent()*100)
})
3. 多个并行进度条
func main() {
uiprogress.Start()
// 创建3个并行进度条
var bars []*uiprogress.Bar
for i := 0; i < 3; i++ {
bars = append(bars, uiprogress.AddBar(100).
PrependFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("任务 %d:", i+1)
}))
}
// 模拟并行任务
var wg sync.WaitGroup
for i, bar := range bars {
wg.Add(1)
go func(bar *uiprogress.Bar, id int) {
defer wg.Done()
for bar.Incr() {
time.Sleep(time.Millisecond * time.Duration(10*(id+1)))
}
}(bar, i)
}
wg.Wait()
}
高级功能
1. 自定义宽度
uiprogress.Width = 50 // 设置全局宽度
2. 自定义进度条字符
bar := uiprogress.AddBar(100).
SetEmpty(' '). // 空进度字符
SetFill('▓'). // 填充字符
SetHead('>'). // 头部字符
SetLeftBorder('|'). // 左边框
SetRightBorder('|') // 右边框
3. 手动控制进度
bar := uiprogress.AddBar(100)
for i := 0; i <= 100; i++ {
bar.Set(i) // 直接设置进度值
time.Sleep(time.Millisecond * 50)
}
4. 完成后操作
bar := uiprogress.AddBar(100)
bar.SetOnComplete(func(b *uiprogress.Bar) {
fmt.Println("\n任务完成!")
})
完整示例
package main
import (
"fmt"
"sync"
"time"
"github.com/gosuri/uiprogress"
)
func main() {
uiprogress.Start() // 开始渲染
defer uiprogress.Stop() // 程序退出时停止
// 设置全局宽度
uiprogress.Width = 60
// 创建3个进度条模拟并行任务
var bars []*uiprogress.Bar
for i := 0; i < 3; i++ {
bar := uiprogress.AddBar(100).
PrependFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("任务 %d:", i+1)
}).
AppendFunc(func(b *uiprogress.Bar) string {
return fmt.Sprintf("(%.1f%%)", b.CompletedPercent()*100)
}).
SetOnComplete(func(b *uiprogress.Bar) {
fmt.Printf("\n任务 %d 已完成!\n", i+1)
})
// 自定义样式
bar.SetEmpty(' ').
SetFill('▓').
SetHead('>').
SetLeftBorder('[').
SetRightBorder(']')
bars = append(bars, bar)
}
// 模拟并行任务
var wg sync.WaitGroup
for i, bar := range bars {
wg.Add(1)
go func(bar *uiprogress.Bar, id int) {
defer wg.Done()
for i := 0; i <= 100; i++ {
bar.Set(i)
time.Sleep(time.Millisecond * time.Duration(50*(id+1)))
}
}(bar, i)
}
wg.Wait()
fmt.Println("所有任务完成!")
}
注意事项
- 确保在程序退出前调用
uiprogress.Stop()
清理终端 - 在Docker容器中使用时可能需要设置
uiprogress.Out = os.Stderr
- 进度条不适合在非终端环境使用,应先检测
isatty.IsTerminal(os.Stdout.Fd())
uiprogress库简单易用,适合大多数命令行进度显示需求。对于更复杂的需求,可以考虑其他库如 cheggaaa/pb
或 schollz/progressbar
。