由于是从Python转过来学习go的,之前有用过pyqt5,用designer自动布局,生成界面代码,然后一键运行和打包,都比较方便。无奈运行效率超级底下,且打包体积巨大。
go这边常见的有tk3,walk等,详细对比后,选择了fyne,具体理由如下:
1.在所有go gui框架里面,github上star最高,且更新频繁。
2.安装部署比较简单,只需要配置一个GCC编译环境即可运行。
3.代码和框架比较原生go,使用起来会舒适很多。
4.可以直接run运行,无需很多框架一样,必须用特定命令打包才行。
网上很多教程我看了很多都是直接用的官网的例子,所以专门写一篇,把自己最近几天学到的分享给大家。
网上安装的教程较多,这里我就不仔细介绍了,主要有以下几个步骤:
安装TDM-DCC :配置gcc的运行环境,否则会提示编译无法通过,链接如下安装fyne :也就是拉取fyne框架https://jmeubank.github.io/tdm-gcc/
注:也可以用mingw等gcc代替,我是觉得这个比较轻量化,安装配置简单。
go get fyne.io/fyne/v2
。如是go mod打开了,此文件会安装到%GOPATH%\pkg\mod路径下,没打开mod模式则在%GOPATH%的github.com目录下。安装fyne.exe:用于后续打包用。 go get fyne.io/fyne/cmd/fyne
,若%GOPATH%bin下有了fyne.exe则成功了。接下来就可以开始码代码然后运行了。我这个程序的界面如下
界面主要实现了,读取生成Excel,txt等功能。下面介绍各个函数和模块的使用(主要是界面布局的方式)。 init汉化
fyne原生并不支持中文,所以其界面上显示和输入汉字会出错。可用init函数引用字体的方式解决。
func init() {
fontPaths := findfont.List()
for _, fontPath := range fontPaths {
fmt.Println(fontPath)
//楷体:simkai.ttf
//黑体:simhei.ttf
if strings.Contains(fontPath, "simkai.ttf") {
err := os.Setenv("FYNE_FONT", fontPath)
if err != nil {
return
}
break
}
}
}
然后在main函数末尾中添加如下代码即可。
err := os.Unsetenv("FYNE_FONT")
if err != nil {
return
}
PS:网上很多人说这种方式打包的EXE还是无法支持中文,我这里实测的是可以的,可能是新版本fyne已经添加支持了。
main主函数(控制循环和界面配置)func main() {
//新建一个app
a := app.New()
//新建一个窗口
w := a.NewWindow("近场自动化程序V1.0")
//主界面框架布局
MainShow(w)
//尺寸
w.Resize(fyne.Size{Width: 400, Height: 80})
//w居中显示
w.CenterOnScreen()
//循环运行
w.ShowAndRun()
err := os.Unsetenv("FYNE_FONT")
if err != nil {
return
}
}
main函数尽量简介一点。
MainShow 主界面函数主要是调整布局,需要新建各个widget然后组合放入布局里面。熟悉之后非常简单。
// MainShow 主界面函数
func MainShow(w fyne.Window) {
title := widget.NewLabel("近场自动化程序")
hello := widget.NewLabel("文件夹路径:")
entry1 := widget.NewEntry()
dia1 := widget.NewButton("打开", func() {
fd := dialog.NewFileOpen(func(reader fyne.URIReadCloser, err error) {
if err != nil {
dialog.ShowError(err, w)
return
}
if reader == nil {
log.Println("Cancelled")
return
}
entry1.SetText(reader.URI().Path())
}, w)
fd.SetFilter(storage.NewExtensionFileFilter([]string{".xlsx"}))
fd.Show()
})
label2 := widget.NewLabel("切面方式:")
text := widget.NewMultiLineEntry()
text.Disable()
//labelLast := widget.NewLabel("摩比天线技术(深圳)有限公司 ALL Right Reserved")
labelLast := widget.NewLabel(" ")
combox1 := widget.NewSelect([]string{"最大值切面", "固定倾角切面"}, func(s string) { fmt.Println("selected", s) })
label3 := widget.NewLabel("极化方式:")
combox2 := widget.NewSelect([]string{"±45极化", "H/V极化"}, func(s string) { fmt.Println("selected", s) })
label4 := widget.NewLabel("结果文件夹:")
entry2 := widget.NewEntry()
dia2 := widget.NewButton("打开", func() {
dialog.ShowFolderOpen(func(list fyne.ListableURI, err error) {
if err != nil {
dialog.ShowError(err, w)
return
}
if list == nil {
log.Println("Cancelled")
return
}
//out := fmt.Sprintf(list.String())
entry2.SetText(list.Path())
}, w)
})
combox1.SetSelectedIndex(0)
combox2.SetSelectedIndex(0)
bt3 := widget.NewButton("生成脚本", func() {
if (entry1.Text != "") && (entry2.Text != "") {
text.SetText("")
text.Refresh()
txtInfo := generateTxt(entry1.Text, entry2.Text, combox2.Selected, w)
text.SetText("TXT脚本生成成功。请复制下面的路径信息:\n" + txtInfo)
text.Refresh()
} else {
dialog.ShowError(errors.New("读取Excel文件错误"), w)
}
})
bt4 := widget.NewButton("汇总结果", func() {
fmt.Println(entry2.Text)
if entry2.Text != "" {
bt2(entry2.Text, combox1.Selected, combox2.Selected, text)
} else {
dialog.ShowError(errors.New("文件夹路径错误"), w)
}
})
head := container.NewCenter(title)
v1 := container.NewBorder(layout.NewSpacer(), layout.NewSpacer(), hello, dia1, entry1)
v2 := container.NewHBox(label2, combox1)
v3 := container.NewHBox(label3, combox2)
v4 := container.NewBorder(layout.NewSpacer(), layout.NewSpacer(), label4, dia2, entry2)
v5 := container.NewHBox(bt3, bt4)
v5Center := container.NewCenter(v5)
ctnt := container.NewVBox(head, v1, v2, v3, v4, v5Center, text, labelLast)
w.SetContent(ctnt)
}
PS:以上调用了dialog模块的两个浏览文件夹的功能,但是其内部显示都仍旧是英文的,显示的内容还是跟其他成熟框架有不少差距,唯一的缺陷了。
打包
这里需要在go mod过的ide里运行,直接在文件夹里面命令行是不太行的,没mod环境。打包完成了,大概27M大小,点击响应非常快(比Python的体积小太多了,运行速度快太多了)。效果图如下:
没了,文档写完了,再写多无益,多尝试尝试,非常OK的,还可以跨平台开发,开发效率和运行效率都还可以。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)