# 使用 fyne 编写计算器程序

## 控件布局

display := widget.NewEntry()
display.MultiLine = true

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 回调后面介绍。

AC
+/-
%


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,
)

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,
),
)

container := fyne.NewContainerWithLayout(
layout.NewVBoxLayout(),
display,
clearContainer,
digitContainer,
zeroContainer,
)

## 按钮响应

func clear(display *widget.Entry) func() {
return func() {
display.Text = ""
display.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()
}
}

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()
}
}

## 打包

\$ fyne package -os windows -icon icon.jpg

## 参考

1. fyne GitHub： https://github.com/fyne-io/fyne
2. fyne 官网： https://fyne.io/
3. fyne 官方入门教程： https://developer.fyne.io/tour/introduction/hello.html
4. Go 每日一库 GitHub： https://github.com/darjun/go-daily-lib