使用 fyne 編寫一個計算器程序

簡介

在上一篇文章中,咱們介紹了一個 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😄

參考

  1. fyne GitHub:github.com/fyne-io/fyn…
  2. fyne 官網:fyne.io/
  3. fyne 官方入門教程:developer.fyne.io/tour/introd…
  4. Go 每日一庫 GitHub:github.com/darjun/go-d…

個人博客:darjun.github.io

歡迎關注個人微信公衆號【GoUpUp】,共同窗習,一塊兒進步~

相關文章
相關標籤/搜索