Terminal UI
Posted on
之前用命令行版本的网易云音乐来听歌( musicbox
,在 github
上可以搜索到),觉得实在是太 geek
了,但它是用 python
写的,略微容易崩,所以决定试着用 golang
仿造一个,第一步肯定是模仿它的 UI
了,在浏览器中我们用三元老 HTML/CSS/JS
可以很容易撸出一套能看的前端界面来,但估计没几个人知道命令行版本的 UI
应该怎么搞,其实说实话我也不知道,大概搜了一下,发现用 termui
这个库就可以比较轻松撸出一个与 musicbox
类似的界面了,下面我们来看一下如何用代码来实现吧。
termui 安装
一般来说我们可以使用 go get
来进行获取安装,但最好使用 dep
来帮助我们管理项目的相关依赖。
go get -u github.com/gizak/termui
然后在代码中 import
就可以了。
import "github.com/gizak/termui"
初始化
在使用 termui
时需要先进行初始化( termui.Init()
),并且最后还要释放资源 defer termui.Close()
。
1 2 3 4 5
| err := termui.Init() if err != nil { panic(err) } defer termui.Close()
|
界面相关数据准备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| strs := []string{ " 0. 排行榜", " 1. 艺术家", " 2. 新碟上架", " 3. 精选歌单", " 4. 我的歌单", " 5. 主播电台", " 6. 每日推荐", " 7. 私人FM", " 8. 搜索", " 9. 帮助", }
off := []string{ " 0. 排行榜", " 1. 艺术家", " 2. 新碟上架", " 3. 精选歌单", " 4. 我的歌单", " 5. 主播电台", " 6. 每日推荐", " 7. 私人FM", " 8. 搜索", " 9. 帮助", } on := []string{ "[-> 0. 排行榜](fg-cyan)", "[-> 1. 艺术家](fg-cyan)", "[-> 2. 新碟上架](fg-cyan)", "[-> 3. 精选歌单](fg-cyan)", "[-> 4. 我的歌单](fg-cyan)", "[-> 5. 主播电台](fg-cyan)", "[-> 6. 每日推荐](fg-cyan)", "[-> 7. 私人FM](fg-cyan)", "[-> 8. 搜索](fg-cyan)", "[-> 9. 帮助](fg-cyan)", }
|
定义界面参数
在使用 termui
时,我们需要确定界面元素及其属性,以及它在命令行中的排版,其实 UI
就是对数据的一种呈现,反正就是你觉得怎么好看就怎么来。
1 2 3 4 5 6 7
| ls := termui.List() ls.Items = strs ls.ItemFgColor = termui.ColorWhite ls.BorderLabel = "网易云音乐" ls.Height = 12 ls.Width = 20 ls.Y = 0
|
termui对事件的处理
termui
对事件的处理和 HTTP
处理事件的做法类似,我们需要对不同的事件注册回调函数,例如检测到用户输入 q
,我们注册一个类似的回调函数就可以了。
1 2 3
| termui.Handle("/sys/kbd/q", func(termui.Event) { termui.StopLoop() })
|
相关事件可以是键盘输入,界面点击,窗口伸缩甚至可以是自定义事件。相关事件触发后,对应的数据可能会发生改变,这样以来用户界面就需要发生改变,我们可以使用 termui.Render
对界面重新进行渲染。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| cursor := 0 termui.Render(ls) termui.Handle("/sys/kbd/j", func(termui.Event) { strs[cursor%len(strs)] = off[cursor%len(strs)] cursor++ if cursor == len(strs) { cursor = 0 } strs[cursor%len(strs)] = on[cursor%len(strs)] termui.Render(ls) }) termui.Handle("/sys/kbd/k", func(termui.Event) { strs[cursor%len(strs)] = off[cursor%len(strs)] cursor-- if cursor < 0 { cursor = len(strs) - 1 } strs[cursor%len(strs)] = on[cursor%len(strs)] termui.Render(ls) }) termui.Loop()
|