GO GUI之fyne实例(安装配置和实例代码)

GO GUI之fyne实例(安装配置和实例代码),第1张

为什么选择fyne

由于是从Python转过来学习go的,之前有用过pyqt5,用designer自动布局,生成界面代码,然后一键运行和打包,都比较方便。无奈运行效率超级底下,且打包体积巨大。
go这边常见的有tk3,walk等,详细对比后,选择了fyne,具体理由如下:
1.在所有go gui框架里面,github上star最高,且更新频繁。
2.安装部署比较简单,只需要配置一个GCC编译环境即可运行。
3.代码和框架比较原生go,使用起来会舒适很多。
4.可以直接run运行,无需很多框架一样,必须用特定命令打包才行。
网上很多教程我看了很多都是直接用的官网的例子,所以专门写一篇,把自己最近几天学到的分享给大家。

fyne的安装配置

网上安装的教程较多,这里我就不仔细介绍了,主要有以下几个步骤:

安装TDM-DCC :配置gcc的运行环境,否则会提示编译无法通过,链接如下

https://jmeubank.github.io/tdm-gcc/
注:也可以用mingw等gcc代替,我是觉得这个比较轻量化,安装配置简单。

安装fyne :也就是拉取fyne框架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的,还可以跨平台开发,开发效率和运行效率都还可以。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/989687.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存