Go言語でGUIプログラム on Windows
VisualuRubyが使用できなくなってから、exeファイル単体で動作して、かつ、ファイルサイズが巨大にならないGUIアプリ制作環境を探していましたが、Go言語+WALKライブラリがなかなか良さげなのでメモ。
後述のhello.exeの実行ファイルのサイズは5MB弱で、Windows 8.1(32bit)でコンパイルした実行ファイルがWindows Vistaでも動作しました。
入手先
- Go言語:http://golang-jp.org/
- WALKライブラリ:lxn/walk - GitHub
その他
- play.golang.org : Go言語をインストールしていなくても簡単なプログラムを実行できるので便利。
- 購入した本(GUI関連の記載はありません)
- 作者: 古川昇
- 出版社/メーカー: シーアンドアール研究所
- 発売日: 2015/07/17
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
- こんな本も出版されました(2016/04追記)
- 作者: 松尾愛賀
- 出版社/メーカー: 翔泳社
- 発売日: 2016/04/15
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (5件) を見る
- さらに追加(2016/06追記)
プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)
- 作者: Alan A.A. Donovan,Brian W. Kernighan,柴田芳樹
- 出版社/メーカー: 丸善出版
- 発売日: 2016/06/20
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (2件) を見る
インストール
Go言語本体はmsi(今回は go1.4.2.windows-386.msi)をダウンロードして、そのままインストールする。デフォルトインストール先はC:\GO です。
zipを使用した場合は、環境変数GOROOTを設定(C:\GO)する。
WALKライブラリは以下のコマンドを実行する。(要Git他)
go get github.com/lxn/walk
今回はPCに必要なアプリ(Git)をインストールしていなかったので、walkフォルダ、winフォルダのzipファイルをダウンロードして、C:\GO\src以下に展開しました。
C:\Go\src\github.com\lxn\walk\* C:\Go\src\github.com\lxn\win\*
コンパイル
ソースを置いた場所で以下のコマンドを実行します。
go build src.go CUIアプリ go build -ldflags="-H windowsgui" src.go GUIアプリ(DOS窓を表示させない) go build -ldflags="-s -H windowsgui" src.go stripをかけてサイズ縮小
コマンドで、ソースファイル名を省略した場合(同package名の複数ソースファイルがある場合など?)は「フォルダ名」.exeが作成されます。またWALKライブラリを使用する場合は「実行ファイル名」.manifestという名前のマニフェストファイルを同じ場所に置いておかないと起動しないので注意が必要。マニフェストファイルはコピーしてファイル名だけを変更して(内容はいじらない)使いまわせます。
サンプル
当方Go言語関連の記事も参照ください。
以下は、ボタンをクリックすると"Hello 世界!"と表示するプログラムです。ソースはutf-8で保存します。
ライブラリの使用方法は参考サイトや、ライブラリのexampleを参照のこと、VisualuRubyを使用していたのでそんなに違和感なく使用できそうです。
hello.go
package main import ( "github.com/lxn/walk" . "github.com/lxn/walk/declarative" ) import ( // "fmt" "log" ) type MyMainWindow struct { *walk.MainWindow textArea *walk.TextEdit } func main() { mw := &MyMainWindow {} // Windowのレイアウト // // MainWindow // TextEdit // PushButton // MW := MainWindow{ AssignTo: &mw.MainWindow, // Widgetを実体に割り当て Title: "Hello", MinSize: Size {300, 400}, Layout: VBox {}, // ウィジェットを垂直方向に並べる Children: []Widget { // ウィジェットを入れるスライス TextEdit { // 最初のウィジェット(テキスト) AssignTo: &mw.textArea, }, PushButton { // 次のウィジェット(ボタン) Text: "Hello!", // PushButtonは割り当てしない? // 内部にデータを持たない為? OnClicked: mw.pbClicked, // ボタンクリックイベント }, }, } if _, err := MW.Run(); err != nil { log.Fatal(err) } } // ボタンクリック時の処理 func (mw *MyMainWindow) pbClicked() { const s string = "Hello 世界!\r\n" // TextEdit内の改行は\r\n text := mw.textArea text.AppendText(s) // 文字列追加 }
hello.exe.manifest
<?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> </assembly>