使用github.com/lxn/walk建立桌面應用

EddieRuo發表於2021-01-28

使用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 協議》,轉載必須註明作者和本文連結

相關文章