Raspberry Piで動くGUIアプリケーションをGo (Fyne) で書く
aanriiです。
普段はWebエンジニアとして働いており、開発言語として主にGoを使っております。
IoT開発は趣味でぼちぼちやっています。
Raspberry Piアプリケーション開発というと、みなさん大抵Pythonでやられているのか、世に出回っているナレッジも大体Pythonによるものがほとんどです。
そこをなんとか (個人的に一番手に馴染んでいる) Goで出来ないかなと思い、今回それにチャレンジすることとしました。
本稿では、ディスプレイを接続したRaspberry Piで簡単な時計アプリを動かすことを目標にやっていきます。
実装にあたっては、GoのGUIアプリケーションフレームワークであるFyneを使います。
Fyneはマルチプラットフォーム対応しており、macOSやWindows、Linuxはもちろん、Raspberry Piでの動作もサポートされております。
このため、開発PCで作ったGUI画面を、全く同じようにRaspberry Piでも動作させることができます。
当方では、以下の環境で動作を確認しました。
- Raspberry Pi Zero WH
- Raspbian GNU/Linux 11
- Waveshare 3.5inch RPi LCD
- Macbook Pro MacBook Pro (15-inch 2018, 開発PC)
アプリケーションをつくる
まず、手元の開発PCで時計アプリを実装します。
とりあえずプロジェクトを作成します。
$ mkdir rpi-clock
$ cd rpi-clock
$ go mod init rpi-clock
プロジェクトに、これを導入します。
$ go get -u fyne.io/fyne/v2
続いて、コードを描きます。
package main
import (
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"image/color"
"time"
)
const (
// Raspberry Piのディスプレイサイズに合わせること
width = 480
height = 320
)
func main() {
a := app.New()
w := a.NewWindow("clock")
w.Resize(fyne.NewSize(width, height))
t := canvas.NewText("Loading...", color.White)
t.TextSize = 100
t.TextStyle.Bold = true
t.Alignment = fyne.TextAlignCenter
w.SetContent(container.NewCenter(t))
go func() {
tick := time.NewTicker(time.Second)
for {
<-tick.C
t.Text = time.Now().Format("15:04:05")
t.Refresh()
}
}()
w.ShowAndRun()
}
とりあえず手元の開発PCで動かしてみます。
$ go run main.go
以下のような時計が表示されれば成功です。
アプリケーションをRaspberry Piで動かす
ビルドをRaspberry Pi上で行うため、コードをRaspberry Piへ転送します
(ここではrsyncを使いますが、手段はなんでも良いです)。
# ホスト名など、自分の環境にあわせて適宜修正すること
$ rsync -ahv . pi@raspberrypi.local:~/rpi-clock
ここからはRaspberry Pi上で作業します (sshなどで適宜ログインしてください) 。
Fyneを使ったアプリケーションのビルドのために必要なパッケージをインストールします。
$ sudo apt-get install golang gcc libegl1-mesa-dev xorg-dev
続いて、自分が書いたコードをビルドします (初回ビルドはそこそこ時間かかる気がします)。
$ cd ~/rpi-clock
$ go build -v -o app main.go
出来上がった実行ファイルを実行します。
$ ./app
上手くいけば、さきほどと同様の時計GUIがディスプレイに表示されるはずです。
(Optional) Raspberry Pi起動時にアプリケーションも自動起動させる
せっかくなので、Raspberry Piに電源を投入したら自動的にアプリケーションが立ち上がるようにしてみます。
注意点として、X Window Systemが起動した後にアプリケーションを立ち上げないと、上手くいきません。
これを行うためには、まずRaspberry Pi起動時にX Window Systemを立ち上げさせる必要があります。
初期設定のままなら、Desktop Autologinが有効になっているため、何もしなくてもよいはずですが、
これを無効化している場合、sudo raspi-config
でraspi-configを立ち上げ、
System Option > Boot / Auto Login > Desktop Autologinを選択することで、再び有効化できます。
続いて、.xinitrc
というファイルを、ホームディレクトリ直下に以下の内容で作成します。
#!/usr/bin/env bash
~/rpi-clock/app
こうすることで、X Window System起動時に~/rpi-clock/app
コマンドが実行されるため、アプリケーションが自動起動できるようになります。
まとめ
Raspberry Piで動くGUIアプリケーションをGoで作りました。
とにかくFyneの優秀さに驚かされました。
環境設定に必要な手順も少なく、APIもシンプルかつ直感的で、ポータビリティが高く、なかなかよくできていると感じます。
Fyneの存在は、GoによるRaspberry Pi開発のハードルをかなり下げてくれる感触がありました。
Discussion