使用go语言的Console UI

作者: 从火星来 | 来源:发表于2018-09-03 14:39 被阅读172次

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

    如何安装

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

    效果如何

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

    匿名聊天程序

    匿名聊天程序的源代码

    相关文章

      网友评论

      • 69cf49421ddc:macOS 10.14 没有 /dev/tty 了
        从火星来:@ChenBao 到https://github.com/nsf/termbox-go去反应吧,我看gocui是包装了termbox
      • LanceAdd:可以,很棒

      本文标题:使用go语言的Console UI

      本文链接:https://www.haomeiwen.com/subject/vrwbwftx.html