GolangでクロスプラットフォームGUIアプリを作る

スポンサーリンク
プログラミング

GolangでGUIのクロスプラットフォームアプリを作る

fyne-io/fyne というOpenGLを使うライブラリを使います。 この間1.0が出たみたいです。 僕はGolang Weeklyのツイートで知りました。

簡単なタイマーを作ってみる

こんな感じのものを作ります。

スポンサーリンク

リポジトリ

nozo-moto/pomodoro_timer

コード

OpenGLを触ったことがないのでC++とかで使うOpenGLがどうなのかはわからないですが、 Canbasを作ってその上にWidgetを乗せてくみたいな感じでとてもわかりやすいなと思います 雰囲気Flutterぽいなと思いました。

package main

import (
    "fmt"
    "time"

    "fyne.io/fyne"
    "fyne.io/fyne/app"
    "fyne.io/fyne/widget"
    "github.com/nozo-moto/pomodoro_timer/timer"
)

var (
    showTimeLabel widget.Label
)

const (
    countTime = time.Second * 10
)

func init() {
    showTimeLabel.Alignment = fyne.TextAlignCenter
}

func main() {
    showTimeChan := make(chan time.Duration)
    timer := timer.New(countTime, showTimeChan)
    go timer.Run()
    go func() {
        for {
            select {
            case showtime := <-showTimeChan:
                showTimeLabel.SetText(formatTime(showtime))
            }
        }
    }()
    startButton := &widget.Button{
        Text: "Start", OnTapped: func() { timer.Start() },
    }
    stopButton := &widget.Button{
        Text: "Stop", OnTapped: func() { timer.Stop() },
    }

    a := app.New()
    w := a.NewWindow("Timer")
    w.Resize(fyne.Size{Width: 150, Height: 150})

    canvasObjects := []fyne.CanvasObject{
        &widget.Label{Text: "Timer", Alignment: fyne.TextAlignCenter},
        &showTimeLabel,
        startButton,
        stopButton,
    }

    w.SetContent(&widget.Box{Children: canvasObjects})
    timer.Initialize(countTime)
    w.ShowAndRun()
}

func formatTime(t time.Duration) string {
    h := t / time.Hour
    m := (t - h*time.Hour) / time.Minute
    s := (t - h*time.Hour - m*time.Minute) / time.Second

    return fmt.Sprintf("%d:%d:%d", h, m, s)
}

timer.go

package timer

import (
    "time"
)

const timerTime = 1 * time.Second

type Timer struct {
    startTime    time.Time
    showTimeChan chan time.Duration
    CountTime    time.Duration
}

func New(countTime time.Duration, showTime chan time.Duration) *Timer {
    return &Timer{
        startTime:    time.Time{},
        showTimeChan: showTime,
        CountTime:    countTime,
    }
}

func (t *Timer) Run() {
    timeTicker := time.NewTicker(timerTime)
    for {
        select {
        case <-timeTicker.C:
            if t.startTime != (time.Time{}) {
                showtime := t.CountTime - time.Now().Sub(t.startTime)
                if showtime < 0 {
                    t.Stop()
                    break
                }
                t.showTimeChan <- showtime
            }
        }
    }
}

func (t *Timer) Start() {
    t.startTime = time.Now()
}

func (t *Timer) Stop() {
    t.startTime = time.Time{}
    t.showTimeChan <- 0
}

func (t *Timer) Initialize(initalTimer time.Duration) {
    t.showTimeChan <- initalTimer
}

その他

タイマーが終ったのを通知させたり、音楽鳴らしたりしたかったができなかった。

音楽再生と、通知はRoadmapに乗ってるのでそのうちできるんじゃないかなと思います 。

ロードマップには

  • Higher level interaction and workflow definitions – navigation, app scaffold, notifications etc
  • Web-service integration for working with cloud services etc
  • Multimedia integration
  • Interoperability with other applications or UI providers (file pickers, document viewers etc)
  • Payment integration

とあるので後々実装されそうです。

音楽は

 

Golangで音声ファイルを鳴らす
Golangで音声ファイルを鳴らすGoで音声ファイルを鳴らしますgithub.com/faiface/beepを使いますコードpackage mainimport ( "os"

の記事で書いたやり方を試したがこれに組み込むのは無理でした。

 

雑感

GUIクロスプラットフォームアプリだとElectronくらいしかなさそうな上に、大変なのでサクッと作るならこっちの方が楽だなといった印象です。

 

コメント

タイトルとURLをコピーしました