使用go语言的Console UI

go语言的GUI是一大短板,至今没有官方的跨平台GUI,第三方GUI库虽然有一些,例如QT/GTK/wxWidget的绑定,但是跨平台编译还是麻烦。如果我们只是需要一个简单的GUI,那么可以使用Console UI,今天我推荐一个很不错的Console UIgocui,经本人试用,没有额外依赖关系,完全可以在linux平台编译win32程序。

如何安装

它的源代码地址(包引用路径)是:github.com/jroimartin/gocui。但是该程序的中文支持不好,显示中文字符时会漏掉一半文字,因此我给它打了一个补丁,因为该补丁还未被合并到主线中,请从:github.com/rocket049/gocui或者https://gitee.com/rocket049/gocui.git下载源代码,然后复制到目录:GOPATH/src/github.com/jroimartin/gocui

打了补丁的程序和原程序有2个区别:

  1. 可以正确显示中文;
  2. 多了一个专门用于从编辑窗口读入中文的函数:(v *View) ReadEditor() []byte,该函数用于还原输入的中文语句。

如何使用

我就以一个简单的输入、显示程序做一个例子:

//Try cjk patch. example of view.ReadEditor
package main

import (
    "fmt"
    "log"

    "github.com/jroimartin/gocui"
)
// 输出窗口
func viewOutput(g *gocui.Gui, x0, y0, x1, y1 int) error {
    v, err := g.SetView("out", x0, y0, x1, y1)
    if err != nil {
        if err != gocui.ErrUnknownView {
            return err
        }
        v.Wrap = true
        v.Overwrite = false
        v.Autoscroll = true
        v.SelBgColor = gocui.ColorRed
        v.Title = "Messages"
    }
    return nil
}
// 输入窗口(编辑器)
func viewInput(g *gocui.Gui, x0, y0, x1, y1 int) error {
    if v, err := g.SetView("main", x0, y0, x1, y1); err != nil {
        if err != gocui.ErrUnknownView {
            return err
        }
        v.Editable = true
        v.Wrap = true
        v.Overwrite = false
        if _, err := g.SetCurrentView("main"); err != nil {
            return err
        }
        fmt.Fprintf(v, "example,中文输入示例,按回车输入。press ENTER to input。Ctrl-C 退出")
    }
    return nil
}
// 显示输出、输入窗口
func layout(g *gocui.Gui) error {
    maxX, maxY := g.Size()
    if err := viewOutput(g, 1, 1, maxX-1, maxY-4); err != nil {
        return err
    }
    if err := viewInput(g, 1, maxY-3, maxX-1, maxY-1); err != nil {
        return err
    }
    return nil
}
// 退出函数
func quit(g *gocui.Gui, v *gocui.View) error {
    return gocui.ErrQuit
}
func main() {
    g, err := gocui.NewGui(gocui.OutputNormal)
    if err != nil {
        //log.Panicln(err)
    }

    g.Cursor = true
    g.Mouse = false
    g.ASCII = false

    g.SetManagerFunc(layout)
    if err := g.SetKeybinding("main", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
        log.Panicln(err)
    }
    if err := g.SetKeybinding("main", gocui.KeyEnter, gocui.ModNone, updateInput); err != nil {
        log.Panicln(err)
    }
    if err := g.MainLoop(); err != nil && err != gocui.ErrQuit {
        log.Panicln(err)
    }
    g.Close()
}
//updateInput 当按下ENTER键时调用,把输入的内容复制到输出窗口中
func updateInput(g *gocui.Gui, cv *gocui.View) error {
    v, err := g.View("out")
    if cv != nil && err == nil {
        var p = cv.ReadEditor()
        if p != nil {
            v.Write([]byte("你:"))
            v.Write(append(p, '\n'))
        }
        v.Autoscroll = true
    }
    l := len(cv.Buffer())
    cv.MoveCursor(0-l, 0, true)
    cv.Clear()
    return nil
}

效果如何

下面的图片就是我用该程序做的的一个匿名聊天程序界面:

匿名聊天程序

匿名聊天程序的源代码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,523评论 25 708
  • 不知何时开始,习惯听着刘筱磁性而又温暖的声音入睡,一直到最后的那句,晚安,内心深处那昔日尖锐的痛处,在这声音里,得...
    冷冰瞳阅读 130评论 0 0
  • 太难忘的人总是可以在每首慢歌响起, 每个天气变换, 每把雨伞撑开, 每杯牛奶温热, 每对情侣相拥, 每盒橙汁喝完,...
    摩希阅读 443评论 1 1
  • 杨柳依依桃花开, 千里春风笑残雪。 姹紫嫣红俏争艳, 蜂嗡蝶舞采蜜忙。
    爱你的人是我865432阅读 272评论 0 4
  • 明天就要上班,好多事情纷纷扰扰。
    金桔柠檬柚子茶阅读 187评论 0 0