使用github.com/lxn/walk创建桌面应用

使用github.com/lxn/walk创建桌面应用

使用golang创建一个windows桌面翻译应用(第一次发文,有代码或者其他方面的不足,请大家多多指教~~ 谢谢)

一. 准备工作

  1. 桌面应用需要到的包

    1. go > 1.11
    2. github.com/akavel/rsrc
    3. github.com/lxn/walk
  2. 百度翻译api

    1. api申请地址 api.fanyi.baidu.com/
    2. 获得我们需要的 appid / appsecret
  3. 有可能遇到的问题

    1. 运行的时候有可能会遇到缺 cannot find package "golang.org/x/sys/windows" 这个问题, 到你的GOPATH/golang.org/x/ 执行 https://github.com/golang/sys.git 即可

二. 完成后的粗略界面

使用github.com/lxn/walk创建桌面应用

三. 代码实现

package main

import (
    "crypto/md5"
    "encoding/hex"
    "encoding/json"
    "fmt"
    "github.com/lxn/walk"
    . "github.com/lxn/walk/declarative"
    "io/ioutil"
    "log"
    "net/http"
    "strconv"
    "time"
    "translate/logging"
    "translate/util"
)

var (
    BaiduApi  = "https://fanyi-api.baidu.com/api/trans/vip/translate"
    Appid     = "xxxx" // appid
    AppSecret = "xxxx" // appsecret
    from      = "auto"
    to        = "en"
    UserHome  string
)
// 主窗体
type MyMainWindow struct {
    *walk.MainWindow
}

func main() {
    UserHome, _ = util.Home()
    lanMap := make(map[string]string)
    rLanMap := make(map[string]string)
    lanMap["auto"] = "自动检测"
    lanMap["zh"] = "中文"
    lanMap["en"] = "英语"
    lanMap["jp"] = "日语"
    lanMap["ru"] = "俄语"

    rLanMap["自动检测"] = "auto"
    rLanMap["中文"] = "zh"
    rLanMap["英语"] = "en"
    rLanMap["日语"] = "jp"
    rLanMap["俄语"] = "ru"
    mw := new(MyMainWindow)
    var showAboutBoxAction *walk.Action
    var fromMenu *walk.Menu
    var inTE *walk.LineEdit
    var outTE *walk.TextEdit
    var lshow *walk.Label
    ilshow := getLshowContent(from, to, lanMap)
    if err := (MainWindow{
        AssignTo: &mw.MainWindow,
        Title:    "翻译",
        MenuItems: []MenuItem{
            Menu{
                Text: "Action",
                Items: []MenuItem{
                    Action{
                        Text:        "退出",
                        OnTriggered: func() { mw.Close() },
                    },
                },
            },
            Menu{
                Text: "帮助",
                Items: []MenuItem{
                    Action{
                        AssignTo:    &showAboutBoxAction,
                        Text:        "关于",
                        OnTriggered: mw.showAboutTriggered,
                    },
                },
            },
        },
        ToolBar: ToolBar{
            ButtonStyle: ToolBarButtonImageBeforeText,
            Items: []MenuItem{
                Menu{
                    AssignTo: &fromMenu,
                    Text:     "翻译语言",
                    Items: []MenuItem{
                        Action{
                            Text: "自动检测",
                            OnTriggered: func() {
                                from = "auto"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                        Action{
                            Text: "中文",
                            OnTriggered: func() {
                                from = "zh"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                        Action{
                            Text: "英语",
                            OnTriggered: func() {
                                from = "en"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                        Action{
                            Text: "日语",
                            OnTriggered: func() {
                                from = "jp"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                        Action{
                            Text: "俄语",
                            OnTriggered: func() {
                                from = "ru"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                    },
                },
                Separator{},
                Menu{
                    Text: "目标语言",
                    Items: []MenuItem{
                        Action{
                            Text: "中文",
                            OnTriggered: func() {
                                to = "zh"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                        Action{
                            Text: "英语",
                            OnTriggered: func() {
                                to = "en"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                        Action{
                            Text: "日语",
                            OnTriggered: func() {
                                to = "jp"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                        Action{
                            Text: "俄语",
                            OnTriggered: func() {
                                to = "ru"
                                lshow.SetText(getLshowContent(from, to, lanMap))
                            },
                        },
                    },
                },
            },
        },
        MinSize: Size{300, 200},
        Layout:  VBox{},
        Children: []Widget{
            Label{Text: ilshow, AssignTo: &lshow},
            GroupBox{
                Layout: HBox{},
                Font:   Font{PointSize: 14},
                Children: []Widget{
                    LineEdit{AssignTo: &inTE,},
                    PushButton{
                        Text: "翻译",
                        OnClicked: func() {
                            content := inTE.Text()
                            if content != "" {
                                tr, err := translate(content)
                                if err != nil {
                                    mw.showNoneMessage(err.Error())
                                } else {
                                    tf := tr["trans_result"].([]interface{})
                                    str := ""
                                    for _, v := range tf {
                                        v1 := v.(map[string]interface{})
                                        str = str + v1["dst"].(string)
                                    }
                                    outTE.SetText(str)
                                }
                            } else {
                                mw.showNoneMessage("请输入要翻译的内容")
                            }
                        },
                    },
                },
            },
            Label{Text: " 翻译结果 :", Font: Font{PointSize: 14},},
            TextEdit{AssignTo: &outTE, ReadOnly: true, Font: Font{PointSize: 14},},
        },
    }.Create()); err != nil {
        log.Fatal(err)
    }
    mw.Run()
}
func getLshowContent(from, to string, lanMap map[string]string) string {
    return fmt.Sprintf("%s ----- %s", lanMap[from], lanMap[to])
}

func (mw *MyMainWindow) showAboutTriggered() {
    walk.MsgBox(mw, "About", "Powered by golang+lxn/walk",walk.MsgBoxIconInformation)
}

func (mw *MyMainWindow) showNoneMessage(message string) {
    walk.MsgBox(mw, "提示", message, walk.MsgBoxIconInformation)
}

// 请求百度api
func translate(content string) (map[string]interface{}, error) {
    salt := time.Now().Unix()
    sign := encode(content, salt)
    url := fmt.Sprintf("%s?q=%s&from=%s&to=%s&appid=%s&salt=%d&sign=%s", BaiduApi, content, from, to, Appid, salt, sign)
    logging.Info(url, salt)
    client := &http.Client{}
    request, err := http.NewRequest("GET", url, nil)
    //异常捕捉
    if err != nil {
        return nil, err
    }

    //处理返回结果
    response, _ := client.Do(request)
    //关闭流
    defer response.Body.Close()
    body, err := ioutil.ReadAll(response.Body)
    if err != nil {
        return nil, err
    }
    d := make(map[string]interface{})
    err = json.Unmarshal(body, &d)
    if err != nil {
        return nil, err
    }
    return d, nil
}

// 编码
func encode(content string, salt int64) string {
    s := strconv.FormatInt(salt, 10)
    saltStr := Appid + content + s + AppSecret
    logging.Info(saltStr)
    return Md5(saltStr)
}

func Md5(s string) string {
    h := md5.New()
    h.Write([]byte(s))
    return hex.EncodeToString(h.Sum(nil))
}

四.其他

具体代码实现

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 4

感觉写起来不很方便的样子,前端 electron 一把梭比较香 :new_moon_with_face:

3年前 评论

@wj2015 是的,支持一下golang的 主要是 文档太少了

3年前 评论

网络请求过程中会导致窗口无响应吗?

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!