🕙

Raspberry Piで動くGUIアプリケーションをGo (Fyne) で書く

2022/01/23に公開

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

続いて、コードを描きます。

main.go
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開発のハードルをかなり下げてくれる感触がありました。

脚注
  1. Difference between .xinitrc, .xsession and .xsessionrc ↩︎

Discussion