Go Fyneで遊んでみた

# はじめに
こんにちは。@af-2784です。
入社してから1年半、バッチやAPIなど、Goでバックエンド中心の開発をしてきましたが、
たまにはGUIの開発をしてみたい、オシャンな画面を作ってみたい…！
調べてみたら、Goには[Fyne](https://pkg.go.dev/fyne.io/fyne/v2)というGUIライブラリがあると知り、今回はこちらを少し触ってみたいと思います。

# 準備
Fyneをインストールします。

```shell
$ go get fyne.io/fyne/v2/app
$ go get fyne.io/fyne/v2/widget
$ go get fyne.io/fyne/v2/container
$ go get fyne.io/fyne/v2/canvas
```

# Hello World
何事もまずはHello Worldから。
`hello := widget.NewLabel("Hello World!")`のようにウィンドウに表示したいオブジェクトを定義し、SetContentの中に定義したオブジェクトを入れれば、GUIの画面に表示できるようです。


```go
package main

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

func main() {
    a := app.New()
    w := a.NewWindow("Hello")
    hello := widget.NewLabel("Hello World!")

    w.SetContent(container.NewVBox(
        hello,
    ))
    w.ShowAndRun()
}
```

これを実行すると、以下のようなウィンドウが表示されました！

![スクリーンショット 2021-12-08 19.33.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927158/c0a13c7a-8e45-ee2f-3f34-cdb6352fd952.png)


# ボタンの追加
先ほどのHello Worldの画面にボタンを追加し、ウィンドウの中のテキストを変えてみようと思います。
先ほどのコードに以下を追加します。

```go
widget.NewButton("Button", func() {
	hello.SetText("Merry Christmas!")
}),
```
全体像

```go
package main

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

func main() {
    a := app.New()
    w := a.NewWindow("Hello")
    hello := widget.NewLabel("Hello World!")

    w.SetContent(container.NewVBox(
        hello,
        widget.NewButton("Button", func() {
            hello.SetText("Merry Christmas!")
        }),
    ))
    w.ShowAndRun()
}
```

これを実行すると、ボタンが表示されていますね。
![スクリーンショット 2021-12-08 19.34.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927158/a16663d7-beaf-26c5-4256-44dc4210425c.png)

ボタンを押すと、テキストが`Hello World!`から`Merry Christmas!`に変わりました！
![スクリーンショット 2021-12-08 19.34.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927158/6a9da27b-9f94-df2d-8950-5654f6a85bf3.png)

# 終了ボタンを追加する
一般的なGUIアプリケーションんのように、ウィンドウの左上の閉じるボタンを押せば、ウィンドウを閉じることができますが、Fyneを使って閉じるボタンを自作することも可能です。
先ほどのプログラムに以下を追加します。main関数の最初に定義した変数`a := app.New()`に対してQuit()を実行することで、アプリケーションを終了することができるようです。

```go
widget.NewButton("Quit", func() {
       a.Quit()
}),
```

全体像

```go
package main

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

func main() {
    a := app.New()
    w := a.NewWindow("Hello")
    hello := widget.NewLabel("Hello World!")

    w.SetContent(container.NewVBox(
        hello,
        widget.NewButton("Button", func() {
            hello.SetText("Merry Christmas!")
        }),
        widget.NewButton("Quit", func() {
            a.Quit()
        }),
    ))
    w.ShowAndRun()
}
```

これを実行すると、ボタンが１つ増えました。新しく追加された`Quit`ボタンを押したらウィンドウが消えました。
![スクリーンショット 2021-12-08 19.43.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927158/5d6ef931-39d4-fb88-d2b5-8f2e4e45be6a.png)

# オブジェクトを表示したり消したりする
まずは、以下のような変数を定義します。Hello Worldの時に定義したNewLabel()と似て新たなテキストオブジェクトを定義できますが、canvasを使えば、オブジェクトの色を変えたり、オブジェクトを動かしたり、オブジェクトに対して様々な操作を行うことができます。

```go
text := canvas.NewText("Mele Kalikimaka", color.RGBA{255, 0, 0, 255});
```

そして、SetContentの中に以下を追加します。Visible()で対象のオブジェクトが現在、画面に表示されているか確認することができます。オブジェクトが表示されている時は、Hide()でオブジェクトを非表示にし、表示されていない時はShow()でオブジェクトを表示します。

```go
text,
widget.NewButton("ON/OFF", func() {
       if text.Visible() {
           text.Hide()
       } else { 
           text.Show()
       }
}),
```

全体像

```go
package main

import (
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/widget"
    "fyne.io/fyne/v2/container"
    "fyne.io/fyne/v2/canvas"
    "image/color"
)

func main() {
    a := app.New()
    w := a.NewWindow("Hello")
    hello := widget.NewLabel("Hello World!")
    text := canvas.NewText("Mele Kalikimaka", color.RGBA{255, 0, 0, 255});

    w.SetContent(container.NewVBox(
        hello,
        text,
        widget.NewButton("ON/OFF", func() {
            if text.Visible() {
                text.Hide()
            } else { 
                text.Show()
            }
        }),
        widget.NewButton("Button", func() {
            hello.SetText("Merry Christmas!")
        }),
        widget.NewButton("Quit", func() {
            a.Quit()
        }),
    ))
    w.ShowAndRun()
}
```

これを実行してみます。
![スクリーンショット 2021-12-08 20.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927158/fe825f75-6d96-a493-c30c-f790d53f66d6.png)

上の状態で`ON/OFF`ボタンを押すと、`Mele Kalikimaka`という文字が消えました。

![スクリーンショット 2021-12-08 20.14.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927158/84c8c839-ece2-af96-88c5-64ec48318109.png)

そして、もう一度`ON/OFF`ボタンを押すと、`Mele Kalikimaka`が再び表示されました。

![スクリーンショット 2021-12-08 20.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/927158/678b7a21-36e7-4ba0-54fe-b064902f3bd9.png)


# まとめ
Fyneを使いこなせれば、ゲームやメモアプリなど、様々なGUIアプリを作れるようです。以下のサイトでは、Fyneを使った様々なアプリが提供されています。
https://apps.fyne.io/all
今回は初歩的な部分しか触れていませんが、また時間があるときにもっとFyneを触ってみたいと思います。