Go walk 使用体験

📢 この記事は gemini-3.5-flash によって翻訳されました

2024年12月に、人生初のWindows GUIソフトウェア「画面を見ないで、Go walk(散歩に行こう)」を書いてみました。

読み込み中...
- -

非常に簡素なものではありますが、フレームワークをほとんど使わずに開発した初めての感覚でした。また、当時はどうしてもGoを使いたかったのですが、ちょうどテーマにぴったりなフレームワークを見つけ、技術スタック(Go)でテーマ(Go walk)を表現するダブルミーニングにもなっていました。

そのため、今日このノートを再び見返して、非常に感慨深いものがあります。特に、このソフトウェアはi18n(多言語対応)にすら対応していました。AIコーディングが盛んな現在からすると、当時はよくもまあ古典的な方法で手書きして多言語対応まで実装したものだと驚かされます。確かこのフレームワークはネイティブでは多言語に対応していなかった記憶がありますが、使いにくかったこともあり、詳細は忘れてしまいました。

感想はここまでにして、以下はノートの原文です。

この記事は公開当時のノートであり、正確性は保証しません。また、walkアーキテクチャは推奨しません。

環境

GoLandで新しいGoプロジェクトを作成すると、デフォルトで go.mod が初期化されます。もしこのファイルがない場合は、以下のコマンドを使用できます。

1
go mod init

walkのインストール

1
go get github.com/tailscale/walk

プロジェクト

rsrc ツール をダウンロードしてPATHを通した後、rsrcをインストールします。

1
go get github.com/akavel/rsrc

マニフェストファイル main.manifest を作成し、内容は以下の通りとします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="SomeFunkyNameHere" type="win32"/>
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
        </dependentAssembly>
    </dependency>
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
            <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
            <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True</dpiAware>
        </windowsSettings>
    </application>
</assembly>

Goプログラムへのマージ

1
rsrc -manifest main.manifest -o rsrc.syso

カウントダウン開発

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package main

import (
	"fmt"
	"github.com/tailscale/walk"
	. "github.com/tailscale/walk/declarative"
	"log"
	"runtime"
	"time"
)

func main() {
	app, err := walk.InitApp()
	if err != nil {
		log.Fatal(err)
	}

	var timeRemain *walk.Label
	var flag bool
	ok := true

	MainWindow{
		Title:   "Hi walk",                   // ウィンドウタイトル
		MinSize: Size{Width: 60, Height: 40}, // 最小サイズ
		Layout:  VBox{MarginsZero: true},     // ウィンドウレイアウト、垂直ボックスレイアウト
		Children: []Widget{
			Label{
				AssignTo: &timeRemain,
				Text:     "カウントダウン開始 10秒",
			},
			PushButton{
				Text: "カウントダウン開始",
				OnClicked: func() {
					if flag {
						return
					}
					flag = true
					// カウント
					go func() {
						for i := 10; i > 0; i-- {
							if ok {
								time.Sleep(1 * time.Second)
								timeRemain.SetText(fmt.Sprintf("カウントダウン %d 秒", i))
							} else {
								runtime.Goexit()
							}
						}
						walk.MsgBox(nil, "通知", "時間です", walk.MsgBoxIconInformation)
						flag = false
					}()
				},
			},
			PushButton{
				Text: "カウントダウン停止",
				OnClicked: func() {
					flag = false
					ok = false
					timeRemain.SetText("カウントは停止しました")
					time.Sleep(1 * time.Second)
					timeRemain.SetText("カウントダウン開始 10秒")
				},
			},
		},
	}.Create()

	app.Run()
}

新しいウィンドウ

新しいウィンドウを開く

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package main

import (
	"github.com/tailscale/walk"
	. "github.com/tailscale/walk/declarative"
	"log"
)

type MyMainWindow struct {
	*walk.MainWindow
}

func main() {
	app, err := walk.InitApp()
	if err != nil {
		log.Fatal(err)
	}

	mw := new(MyMainWindow)

	MainWindow{
		AssignTo: &mw.MainWindow,
		Title:    "Hi walk",                     // ウィンドウタイトル
		MinSize:  Size{Width: 400, Height: 500}, // 最小サイズ
		Size:     Size{Width: 400, Height: 500}, // サイズ
		Layout:   VBox{},                        // ウィンドウレイアウト
		Children: []Widget{
			Label{
				Text:      "モードを選択してください",
				Alignment: AlignHCenterVCenter,
			},
			PushButton{
				Text:      "短時間・高頻度の休憩",
				OnClicked: mw.shortLayout,
			},
			PushButton{
				Text: "長時間・低頻度の休憩",
			},
		},
	}.Create()

	app.Run()

}

func (mw *MyMainWindow) shortLayout() {
	shortMainWindow := new(MyMainWindow)
	MainWindow{
		AssignTo: &shortMainWindow.MainWindow,
		Title:    "短時間・高頻度の休憩",
		MinSize:  Size{Width: 400, Height: 500}, // 最小サイズ
		Size:     Size{Width: 400, Height: 500}, // サイズ
		Layout:   VBox{},
		Children: []Widget{
			Label{Text: "Hello"},
		},
	}.Create()

	shortMainWindow.Running()
}

Reference

go walkを2日間使ってみた状況、心の中でそっと諦める

Golang—walk学習(一)

walkコントロール学習第一節

This post is licensed under CC BY-NC-SA 4.0 by the author.

アクセス統計

2025-02-08 からのアクセス統計

Hugo で構築されています。 | テーマ StackJimmy によって設計されています。 | yexca によって改修されています。