凯发体育官方-ag凯发国际 > 好文阅读

以下文章来源于goupup ,作者dj

简介

在之前文章中,我们介绍了一个 go 的高颜值 gui 库fyne。本文接着,介绍如何使用fyne编写一个简单的计算器程序。程序效果如下:

控件布局

我们使用widget.entry来显示输入的数字、运算符和运算结果。先创建一个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 := fyne.newcontainerwithlayout(
  layout.newgridlayout(4),
  digitbtns...)

input回调后面介绍。

第一行有 3 个具有特殊效果的按钮:

  • ac:清空显示框;
  • /-:切换正负号;
  • %将数字变为百分数,即除以 100。

外加一个除法按钮。这一行同样使用gridlayout布局:

clearbtn := widget.newbutton("ac", clear(display))
signbtn := widget.newbutton(" /-", sign(display))
percentbtn := widget.newbutton("%", percent(display, "%"))
pidebtn := widget.newbutton("÷", input(display, "÷"))
clearcontainer := fyne.newcontainerwithlayout(
  layout.newgridlayout(4),
  clearbtn,
  signbtn,
  percentbtn,
  pidebtn,
)

几个回调处理后面统一介绍。

最后一行由于0这个按钮宽度是其它按钮的 2 倍。我们先使用gridlayout布局,将这一行平均分成两grid(即每行 2 个控件)。按钮0独占一个grid,由于gridlayout布局中每个grid大小相同,故按钮0有整个行一半的宽度。后一个grid,按钮.和=平分,同样使用一个gridlayout达到这个效果:

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组合到一起:

container := fyne.newcontainerwithlayout(
  layout.newvboxlayout(),
  display,
  clearcontainer,
  digitcontainer,
  zerocontainer,
  ag凯发国际 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: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

本文来自投稿,不代表本网站立场,发布者:实习编辑,如若转载,请注明出处:https://www.fur.net.cn/yuedu/500451.html

关注微信
网站地图