使用github.com/lxn/walk创建桌面应用
使用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 协议》,转载必须注明作者和本文链接
感觉写起来不很方便的样子,前端 electron 一把梭比较香 :new_moon_with_face:
@wj2015 是的,支持一下golang的 主要是 文档太少了
网络请求过程中会导致窗口无响应吗?