在上一篇文章中,咱们介绍了一个 Go 的高颜值 GUI 库fyne
。本文接着上一篇,介绍如何使用fyne
编写一个简单的计算器程序。程序效果以下:html
咱们使用widget.Entry
来显示输入的数字、运算符和运算结果。先建立一个widget.Entry
对象,设置可显示多行:git
display := widget.NewEntry()
display.MultiLine = true
复制代码
其它数字和符号控件都用widget.Button
来表示。按钮也分为两种,一种是没有特殊效果的,点击后直接在显示框中添加对应的字符便可。一种是有特殊效果的,例如清空显示框(AC
)、进行计算(=
)。中间三行按钮都是前一种,咱们使用GridLayout
来布局,每行显示 4 个:github
digits := []string{
"7", "8", "9", "×",
"4", "5", "6", "-",
"1", "2", "3", "+",
}
var digitBtns []fyne.CanvasObject
for _, val := range digits {
digitBtns = append(digitBtns, widget.NewButton(val, input(display, val)))
}
digitContainer := fyne.NewContainerWithLayout(
layout.NewGridLayout(4),
digitBtns...)
复制代码
input
回调后面介绍。golang
第一行有 3 个具备特殊效果的按钮:编程
AC
:清空显示框;+/-
:切换正负号;%
将数字变为百分数,即除以 100。外加一个除法按钮。这一行一样使用GridLayout
布局:windows
clearBtn := widget.NewButton("AC", clear(display))
signBtn := widget.NewButton("+/-", sign(display))
percentBtn := widget.NewButton("%", percent(display, "%"))
divideBtn := widget.NewButton("÷", input(display, "÷"))
clearContainer := fyne.NewContainerWithLayout(
layout.NewGridLayout(4),
clearBtn,
signBtn,
percentBtn,
divideBtn,
)
复制代码
几个回调处理后面统一介绍。微信
最后一行因为0
这个按钮宽度是其它按钮的 2 倍。咱们先使用GridLayout
布局,将这一行平均分红两Grid
(即每行 2 个控件)。按钮0
独占一个Grid
,因为GridLayout
布局中每一个Grid
大小相同,故按钮0
有整个行一半的宽度。后一个Grid
,按钮.
和=
平分,一样使用一个GridLayout
达到这个效果:app
zeroBtn := widget.NewButton("0", input(display, "0"))
dotBtn := widget.NewButton(".", input(display, "."))
equalBtn := widget.NewButton("=", equals(display))
zeroContainer := fyne.NewContainerWithLayout(
layout.NewGridLayout(2),
zeroBtn,
fyne.NewContainerWithLayout(
layout.NewGridLayout(2),
dotBtn,
equalBtn,
),
)
复制代码
最后咱们将全部部分用垂直的BoxLayout
组合到一块儿:ide
container := fyne.NewContainerWithLayout(
layout.NewVBoxLayout(),
display,
clearContainer,
digitContainer,
zeroContainer,
copyright,
)
复制代码
在实际开发中,通常会组合使用多种布局实现界面效果。函数
清空按钮响应比较简单,直接将显示框的Text
设置为空便可:
func clear(display *widget.Entry) func() {
return func() {
display.Text = ""
display.Refresh()
}
}
复制代码
注意,要调用Entry.Refresh()
方法刷新界面。因为按钮响应都是对应显示框进行操做,因此都须要传入该对象。
咱们设计在显示框中显示两行,第一行是上次计算的表达式,第二行是本次的。切换正负号在本次只输入一个数字时将该数字的正负号进行切换:
func sign(display *widget.Entry) func() {
return func() {
lines := strings.Split(display.Text, "\n")
if len(lines) == 0 {
return
}
line := lines[len(lines)-1]
value, err := strconv.ParseInt(line, 10, 64)
if err != nil {
return
}
lines[len(lines)-1] = strconv.FormatInt(-value, 10)
display.Text = strings.Join(lines, "\n")
}
}
复制代码
输入回调咱们只作了简单的处理——将对应字符串拼接到显示框中:
func input(display *widget.Entry, value string) func() {
return func() {
display.Text += value
display.Refresh()
}
}
复制代码
计算表达式的函数也很简单,我这里使用了govaluate
库(能够看我以前的文章):
func equals(display *widget.Entry) func() {
return func() {
lines := strings.Split(display.Text, "\n")
if len(lines) == 0 {
return
}
line := lines[len(lines)-1]
line = strings.Trim(line, "+÷×")
exprLine := strings.Replace(line, "÷", "/", -1)
exprLine = strings.Replace(exprLine, "×", "*", -1)
expr, _ := govaluate.NewEvaluableExpression(exprLine)
result, _ := expr.Evaluate(nil)
line += "=\n"
line += fmt.Sprint(result)
display.Text = line
display.Refresh()
}
}
复制代码
注意,这里作了一点容错,把先后多余的运算符去掉了。另外,咱们前面为了显示,使用了÷
表示除法符号,×
表示乘法符号。要使用govaluate
,必须将它们分别替换为/
和*
。
至此计算器就编写完成了,下面咱们介绍如何打包。
准备好一张图片资源做为图标,放到项目目录下:
打包:
$ fyne package -os windows -icon icon.jpg
复制代码
在同目录下生成了一个.exe
文件和一个.syso
文件。如今可直接点击calculator.exe
运行程序,没有其余依赖。
本文介绍如何使用fyne
编写一个简单的计算器程序,主要介绍如何组合使用多种布局。固然计算器功能和错误处理还不完善,并且实现偏过程式编程,感兴趣的可自行完善。完整代码在fyne/calculator
中。
你们若是发现好玩、好用的 Go 语言库,欢迎到 Go 每日一库 GitHub 上提交 issue😄
个人博客:darjun.github.io
欢迎关注个人微信公众号【GoUpUp】,共同窗习,一块儿进步~