使用github.com/lxn/walk建立桌面應用
使用golang建立一個windows桌面翻譯應用(第一次發文,有程式碼或者其他方面的不足,請大家多多指教~~ 謝謝)
一. 準備工作
桌面應用需要到的包
- go > 1.11
- github.com/akavel/rsrc
- github.com/lxn/walk
百度翻譯api
- api申請地址 api.fanyi.baidu.com/
- 獲得我們需要的 appid / appsecret
有可能遇到的問題
- 執行的時候有可能會遇到缺
cannot find package "golang.org/x/sys/windows"
這個問題, 到你的GOPATH/golang.org/x/
執行https://github.com/golang/sys.git
即可
- 執行的時候有可能會遇到缺
二. 完成後的粗略介面
三. 程式碼實現
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 協議》,轉載必須註明作者和本文連結