多くの GUI アプリケーション・フレームワークにおいて、レイアウトは重要です。
wxGo では、コンテナー(container)と呼ばれるもので、GUI パーツをレイアウトしていきます。
package main
import "github.com/dontpanic92/wxGo/wx"
func main() {
app := wx.NewApp()
frame := wx.NewFrame(wx.NullWindow, -1, "Panel")
panel := wx.NewPanel(frame, -1)
wx.NewButton(panel, -1, "button 1", wx.NewPoint(150, 50), wx.DefaultSize, 0)
wx.NewButton(panel, -1, "button 2", wx.NewPoint(15, 15), wx.DefaultSize, 0)
wx.NewButton(panel, -1, "button 3", wx.NewPoint(100, 100), wx.DefaultSize, 0)
frame .Show()
app .MainLoop()
}
ターミナルで、panel.go を保存したディレクトリに移動して、次のコードを実行してください。
go run panel.go
実行結果が表示されるまで、少し時間がかかります。
ウィンドウの大きさをいろいろ変えてみて、レイアウトがどうなるか見てください。アプリケーションを終了するには、ウィンドウを閉じてください。
panel := wx.NewPanel(frame, -1)
コンテナは、内部に GUI パーツ(部品)を配置できる GUI パーツです。
コンテナには、目に見えるものと、目に見えないものがあります。フレームは目に見えるコンテナです。しかしフレームには、GUI パーツを一つしか配置できません。しかも配置した GUI パーツはフレームいっぱいに広がります。そこで、フレームに、別のコンテナを一つ配置するという手法を使います。
パネル(panel)もコンテナの一つです。パネルの第1引数には、パネルを配置するウィンドウを指定します。第2引数には ID を整数値として指定します。wx.ID_ANY もしくは、-1 とすると、一意な整数値が得られます。
wx.NewButton(panel, -1, "button 1", wx.NewPoint(150, 50), wx.DefaultSize, 0)
ボタンを作っています。ボタンの引数を順番に説明すると次のようになります。
package main
import "github.com/dontpanic92/wxGo/wx"
func main() {
app := wx.NewApp()
frame := wx.NewFrame(wx.NullWindow, -1, "Box Sizer")
panel := wx.NewPanel(frame, -1)
vBox := wx.NewBoxSizer(wx.VERTICAL)
hBox := wx.NewBoxSizer(wx.HORIZONTAL)
panel .SetSizer(vBox)
textCtrl:= wx.NewTextCtrl(panel, -1, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE)
vBox .Add(textCtrl, 1, wx.ALL|wx.EXPAND, 5)
vBox .Add(hBox, 0, wx.ALIGN_RIGHT|wx.RIGHT|wx.BOTTOM, 5)
cancel := wx.NewButton(panel, -1, "Cancel", wx.DefaultPosition, wx.DefaultSize, 0)
ok := wx.NewButton(panel, -1, "OK", wx.DefaultPosition, wx.DefaultSize, 0)
hBox .Add(ok)
hBox .Add(cancel, 0, wx.LEFT, 5)
frame .Show()
app .MainLoop()
}
ターミナルで、boxsizer.go を保存したディレクトリに移動して、次のコードで実行してください。
go run boxsizer.go
実行結果が表示されるまで、少し時間がかかります。
ウィンドウの大きさをいろいろと変えてみて、レイアウトがどうなるか見てください。 アプリケーションを終了するには、ウィンドウを閉じてください。
vBox := wx.NewBoxSizer(wx.VERTICAL)
hBox := wx.NewBoxSizer(wx.HORIZONTAL)
panel .SetSizer(vBox)
wx.NewBoxSizer の引数で wx.VERTICAL を指定すると、その Box Sizer コンテナには、GUI パーツが上から順番に縦にに並べられます。
wx.NewBoxSizer の引数で wx.HORIZONTAL を指定すると、その Box Sizer コンテナには、GUI パーツが左から順番に横にに並べられます。
フレームには、一つの GUI パーツしか配置できません。そこでまずフレームにパネルを配置します。そしてパネルの SetSizer メソッドでパネルに vBox を配置します。vBox コンテナには GUI パーツをいつくでも配置です。
フレームに直接 vBox を配置することもできます。しかしまずパネルを配置することによって、TextCtrl 以外のところをクリックして、TextCtrl のフォーカス(選択)を解くことができるようになります。
textCtrl:= wx.NewTextCtrl(panel, -1, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE)
wxWidgets には、文字列を入力できる GUI パーツは、TextCtrl しかありません。第6引数に、wx.TE_MULTILINE を指定すると、複数行入力できるテキストアリアになり、指定しないと一行だけ入力できるテキストフィールドになります。
引数を順番に説明すると次のようになります。
vBox .Add(textCtrl, 1, wx.ALL|wx.EXPAND, 5)
vBox .Add(hBox, 0, wx.ALIGN_RIGHT|wx.RIGHT|wx.BOTTOM, 5)
BoxSizer の Add メソッドで、その BoxSizer に GUI パーツを追加できます。BoxSizer に BoxSizer を追加することもできます。
引数を順番に説明すると次のようになります。
cancel := wx.NewButton(panel, -1, "Cancel", wx.DefaultPosition, wx.DefaultSize, 0)
ok := wx.NewButton(panel, -1, "OK", wx.DefaultPosition, wx.DefaultSize, 0)
ボタンを作っています。第6引数に 1 を指定すると、ボタンの大きさが、ボタンの中に表示される文字列の大きさになります。0 を指定するとボタンの大きさは、デフォルトの大きさのままです。
hBox .Add(ok)
hBox .Add(cancel, 0, wx.LEFT, 5)
hBox にボタンを二つ追加しています。cancel ボタンを追加する場合の第2引数は、0 としても 1 としても表示結果に影響はありません。第2引数を指定しないと、第3引数が認識できないので、意味のない第2引数も指定しています。
package main
import "github.com/dontpanic92/wxGo/wx"
func main() {
app := wx.NewApp()
frame := wx.NewFrame(wx.NullWindow, -1, "Flex Grid Sizer")
panel := wx.NewPanel(frame, -1)
vBox := wx.NewBoxSizer(wx.VERTICAL)
fGrid := wx.NewFlexGridSizer(3, 2, 9, 25)
title := wx.NewStaticText(panel, -1, "Title")
author := wx.NewStaticText(panel, -1, "Author")
review := wx.NewStaticText(panel, -1, "Review")
tcl1 := wx.NewTextCtrl(panel, -1/*, "火花"*/)
tcl2 := wx.NewTextCtrl(panel, -1/*, "又吉直樹"*/)
tcl3 := wx.NewTextCtrl(panel, -1, "", wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE)
fGrid . Add(title)
fGrid . Add(tcl1, 1, wx.EXPAND)
fGrid . Add(author)
fGrid . Add(tcl2, 1, wx.EXPAND)
fGrid . Add(review)
fGrid . Add(tcl3, 1, wx.EXPAND)
fGrid . AddGrowableCol(int64(1))
fGrid . AddGrowableRow(int64(2))
vBox . Add(fGrid, 1, wx.ALL|wx.EXPAND, 10)
panel . SetSizer(vBox)
frame . Show()
app . MainLoop()
}
ターミナルで、flexgridsizer.go を保存したディレクトリに移動して、次のコードで実行してください。
go run flexgridsizer.go
実行結果が表示されるまで、少し時間がかかります。
ウィンドウの大きさをいろいろと変えてみて、レイアウトがどうなるか見てください。アプリケーションを終了するには、ウィンドウを閉じてください。
fGrid := wx.NewFlexGridSizer(3, 2, 9, 25)
Flex Grid Sizerは、GUI パーツをグリッド(grid、格子状)に並べるためのコンテナです。
引数を順番に説明すると次のようになります。
title := wx.NewStaticText(panel, -1, "Title")
Static Textは、入力や編集のできない文字列です。第3引数に表示する文字列を指定します。
fGrid . Add(title)
fGrid . Add(tcl1, 1, wx.EXPAND)
Flex Grid Sizer の Add メソッドは、GUI パーツを左上から最初の行を埋めて、次の行へと順番に埋めていきます。
fGrid . AddGrowableCol(int64(1))
fGrid . AddGrowableRow(int64(2))
この部分が Flex Grid Sizer の特徴的な点です。
AddGrowableCol は、引数で指定した列を、横に拡大します。引数の型は、必ず int64 で指定しなければなりません。
AddGrowableRow は、引数で指定した行を、縦に拡大します。引数の型は、必ず int64 で指定しなければなりません。
vBox . Add(fGrid, 1, wx.ALL|wx.EXPAND, 10)
panel . SetSizer(vBox)
Flex Grid Sizer の周りに、10 ピクセルの隙間(余白)と作るために、vBox に、Flex Grid Sizer を追加しています。そして、vBox をパネルに追加しています。vBox をパネルに追加することにより次のことができるようになります。
タブキーで、テキストコントロール間を移動できるようになります。
テキストコントール以外のところをクリックすることにより、テキストコントロールのフォーカス(選択)を解くことができます。
これらのことは、vBox をフレームに追加するとできなくなります。