package Application import ( "fmt" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/widget" "github.com/Knetic/govaluate" "strconv" "strings" ) /** @author: sre @date: 2022/8/22 0022 @desc: todo **/ // MainShow 主界面函数 func MainShow(w fyne.Window) { //先创建一个widget.Entry对象,设置可显示多行: display := widget.NewEntry() display.MultiLine = true //其它数字和符号控件都用widget.Button来表示。 //按钮也分为两种,一种是没有特殊效果的,点击后直接在显示框中添加对应的字符即可。 //一种是有特殊效果的,例如清空显示框(AC)、进行计算(=)。 //中间三行按钮都是前一种,我们使用GridLayout来布局,每行显示 4 个: 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 := container.New( layout.NewGridLayout(4), digitBtns...) 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 := container.New( layout.NewGridLayout(2), zeroBtn, container.New( layout.NewGridLayout(2), dotBtn, equalBtn, ), ) //最后我们将所有部分用垂直的BoxLayout组合到一起: container := container.New( layout.NewVBoxLayout(), display, clearContainer, digitContainer, zeroContainer, //copyright, ) w.SetContent(container) } // clear 清空按钮响应比较简单,直接将显示框的Text设置为空即可: func clear(display *widget.Entry) func() { return func() { display.Text = "" display.Refresh() } } // sign设计在显示框中显示两行,第一行是上次计算的表达式,第二行是本次的。 // 切换正负号在本次只输入一个数字时将该数字的正负号进行切换: 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 percent(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 } valueFloat := float64(value) / 100 valueStr := strconv.FormatFloat(valueFloat, 'f', -1, 64) lines[len(lines)-1] = valueStr //lines[len(lines)-1] = strconv.FormatInt(-value, 10) display.Text = strings.Join(lines, "\n") display.Refresh() } } // input 输入回调——将对应字符串拼接到显示框中 =号不算 func input(display *widget.Entry, value string) func() { return func() { fmt.Println("ui type value:", value) display.Text += value display.Refresh() } } // equals 计算表达式的函数 go get github.com/Knetic/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, err := govaluate.NewEvaluableExpression(exprLine) if err != nil { display.Text = line + "=" + err.Error() + "\n" display.Refresh() return } result, err := expr.Evaluate(nil) if err != nil { fmt.Println(err) display.Text = line + "=" + err.Error() + "\n" display.Refresh() return } line = line + "=" + fmt.Sprint(result) + "\n" display.Text = line display.Refresh() } }