Introduction to the
In the last article, we introduced Fyne, a Go GUI library with a high appearance level. This article picks up where we left off, showing you how to write a simple calculator program using FYne. The program effect is as follows:
Controls the layout
We use widget.entry to display the entered numbers, operators, and results. Create a widget.Entry object and set it to display multiple lines:
display := widget.NewEntry()
display.MultiLine = true
Copy the code
Other numeric and symbolic controls are represented as widget.button. Buttons are also divided into two kinds, one is no special effect, click directly add the corresponding characters in the display box. One has special effects, such as clearing the display box (AC) and performing calculations (=). The middle three rows of buttons are of the former type. We use GridLayout to display 4 buttons per row:
digits := []string{
"Seven"."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...)
Copy the code
The input callback is covered later.
The first row has three buttons with special effects:
AC
: Clear the display box;+/-
: Toggle signs;%
Convert the number to a percentage, divide by 100.
Plus a division button. This row also uses GridLayout:
clearBtn := widget.NewButton("AC", clear(display))
signBtn := widget.NewButton("+ / -", sign(display))
percentBtn := widget.NewButton("%", percent(display, "%"))
divideBtn := widget.NewButton("The present", input(display, "The present"))
clearContainer := fyne.NewContainerWithLayout(
layout.NewGridLayout(4),
clearBtn,
signBtn,
percentBtn,
divideBtn,
)
Copy the code
Several callback processes are described later.
The last line because of 0 this button is twice as wide as the other buttons. Let’s start with a GridLayout that splits the row evenly into two grids (two controls per row). Button 0 has a Grid to itself, and since every Grid in a GridLayout is the same size, button 0 has half the width of the entire row. The next Grid button. And = bisect, also using a GridLayout to achieve this effect:
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,
),
)
Copy the code
Finally we put all the pieces together with a vertical BoxLayout:
container := fyne.NewContainerWithLayout(
layout.NewVBoxLayout(),
display,
clearContainer,
digitContainer,
zeroContainer,
copyright,
)
Copy the code
In actual development, it is common to combine multiple layouts to achieve interface effects.
Button response
Empty button response is relatively simple, directly set the display box Text to empty:
func clear(display *widget.Entry) func(a) {
return func(a) {
display.Text = ""
display.Refresh()
}
}
Copy the code
Notice that you call the entry.refresh () method to Refresh the interface. Since the button response corresponds to the display box, this object needs to be passed in.
We designed the display box to display two lines, the first line is the last evaluated expression, the second line is the current expression. Toggle The sign of a digit when only one digit is entered:
func sign(display *widget.Entry) func(a) {
return func(a) {
lines := strings.Split(display.Text, "\n")
if len(lines) == 0 {
return
}
line := lines[len(lines)- 1]
value, err := strconv.ParseInt(line, 10.64)
iferr ! =nil {
return
}
lines[len(lines)- 1] = strconv.FormatInt(-value, 10)
display.Text = strings.Join(lines, "\n")}}Copy the code
For the input callback, we simply concatenate the corresponding string into the display box:
func input(display *widget.Entry, value string) func(a) {
return func(a) {
display.Text += value
display.Refresh()
}
}
Copy the code
The function to evaluate an expression is also simple, and I used the GoValuate library here (see my previous article) :
func equals(display *widget.Entry) func(a) {
return func(a) {
lines := strings.Split(display.Text, "\n")
if len(lines) == 0 {
return
}
line := lines[len(lines)- 1]
line = strings.Trim(line, "+ present x")
exprLine := strings.Replace(line, "The present"."/".- 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()
}
}
Copy the code
Notice that we’ve done a little bit of fault-tolerance here, removing the redundant operators before and after. In addition, we used ÷ for division symbol and × for multiplication symbol for display. To use govaluate, you must replace them with/and *, respectively.
Now that we’ve written our calculator, let’s show you how to package it.
packaging
Prepare an image resource as an icon and place it in the project directory:
Packaging:
$ fyne package -os windows -icon icon.jpg
Copy the code
An.exe file and a.syso file are generated in the same directory. You can now run the program directly by clicking Calculator.exe without additional dependencies.
conclusion
This article shows you how to write a simple calculator program using FYne. It mainly shows you how to combine multiple layouts. Of course, the calculator function and error processing is not perfect, and the implementation of partial process programming, interested in their own perfect. The complete code is in FYne/Calculator.
If you find a fun and useful Go library, please Go to GitHub and submit issue😄
reference
- Fyne GitHub:github.com/fyne-io/fyn…
- Fyne official website: fyne. IO /
- Official fyne introductory tutorial: developer. Fyne. IO/tour/introd…
- GitHub: github.com/darjun/go-d…
I
My blog is darjun.github. IO
Welcome to follow my wechat public account [GoUpUp], learn together, progress together ~