2019/06/04

Go言語製のキレイなGUIアプリをFyneライブラリで作るよ!(*´ω`*)

きっかけ

Go言語で社内用のちょっとしたツールを作る時の話です。
ターゲットユーザーがCLIツールでOKな人たちならば、gcliを使ってサクサク作りたい!(●´ω`)ノ
例えばgenerateverifyサブコマンドをもったclitestというツールを作ろうと思ったら、以下を実行するだけでcliとしての大部分が自動生成されます。
gcli new -c generate -c verify clitest
デプロイ先でのファイルハッシュ値とディレクトリ構成をチェックしたい、そんな時に使えるツールをGo言語で作りました!

しかし、世の中そうもいきません。GUIが必要とされる場合も多々あります。そんな折、たまたまGolang WeeklyさんのつぶやきFyneの存在を知りました。

Fyne is awesome

2019/05/27 現在の公式GitHub
100 %ピュアGoな実装でマテリアルデザイン!!₍₍ (ง ˙ω˙)ว ⁾⁾

これだけで踊ってしまうレベル!

使い始めるにあたり、以下の公式のページをざっと読んでおくと良い感じです。


やってみるよ!

こんにちは! (ΦωΦ)

何はともあれ動かしてみましょう。やっぱり最初はご挨拶から。

実装は以下の通りです。GitHubのソースはこちら
package main

import (
 "fyne.io/fyne/app"
 "fyne.io/fyne/widget"
)

func main() {
 a := app.New()

 w := a.NewWindow("Hello")
 w.SetContent(widget.NewVBox(
  widget.NewLabel("Hello Fyne!"),
  widget.NewButton("Quit", func() {
   a.Quit()
  }),
 ))

 w.ShowAndRun()
}

処理内容は以下のような感じですʕ◔ϖ◔ʔ
  1. NewWindowでウィンドウを生成
  2. widgetパッケージからラベルやボタンなどのUI部品を生成してSetContentでウィンドウに追加
    • NewButtonの第2引数には「ボタンが押された時に実行する関数」を指定

メモアプリだよ!

次は簡単なメモアプリを作ってみます(σ´・ω・)

実装は以下のようになります。GitHubのソースはこちら
package main

import (
 "io/ioutil"
 "os"

 "fyne.io/fyne"
 "fyne.io/fyne/app"
 "fyne.io/fyne/dialog"
 "fyne.io/fyne/layout"
 "fyne.io/fyne/widget"

 osdialog "github.com/sqweek/dialog"
)

func main() {
 a := app.New()

 w := a.NewWindow("text pad")
 w.Resize(fyne.NewSize(640, 480))

 le := widget.NewMultiLineEntry()
 le.SetPlaceHolder("Please input your words!")

 bt := widget.NewButton("Save as...", func() {
  filename, err := osdialog.File().Filter("Text files", "txt").Title("Save as a text file").Save()
  if err != nil {
   dialog.ShowError(err, w)
   return
  }
  err = ioutil.WriteFile(filename, []byte(le.Text), os.ModePerm)
  if err != nil {
   dialog.ShowError(err, w)
   return
  }
 })

 box := fyne.NewContainerWithLayout(
  layout.NewBorderLayout(nil, bt, nil, nil),
  le, bt,
 )
 w.SetContent(box)

 w.ShowAndRun()
}

以下がポイントですʕ◔ϖ◔ʔ
  • "Save as.."ボタンを押した時の処理で、ダイアログを伴うファイル保存処理を実行
    • Go言語でクロスプラットフォームなダイアログを扱うなら sqweek/dialog が便利
  • NewContainerWithLayoutでUI部品のレイアウトを指定

Fyneのいろいろ


その他のFyneに関する雑多なトピックを紹介します。

まとめ


実装もビルドもGo言語のみでGUIアプリが作れる点がとても気に入りました。
あまり自分で凝らなくてもデザインがキレイなのもありがたい。
積極的に使っていきたいと思います(*´ω`*)