在上一篇文章中,咱們介紹了一個 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】,共同窗習,一塊兒進步~