wx.BoxSizer (wxPython) | Python-izm

BoxSizer

BoxSizerwxPythonにおける基本的なSizerの一つで、ボタンやテキストなどの部品を縦方向もしくは横方向へ連続して配置します。

横配置

まずは横方向への配置です。処理の順番は下記の通りで13行目から16行目がポイントです。
※ 配置をわかりやすくするためにButtonを使用していますが、Buttonについては別項にて解説します。

  1. アプリケーションの初期化 (3行目)
  2. フレームの初期化 (4行目)
  3. フレームを親としてパネルを初期化 (6行目)
  4. 配置するボタンを初期化 (9-11行目)
  5. BoxSizerを横配置で初期化 (13行目)
  6. BoxSizerへボタンの追加 (14-16行目)
  7. パネルへBoxSizerをセット (18行目)
import wx

application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, 'テストフレーム', size=(400, 200))

panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour('#AFAFAF')

button_1 = wx.Button(panel, wx.ID_ANY, 'ボタン1')
button_2 = wx.Button(panel, wx.ID_ANY, 'ボタン2')
button_3 = wx.Button(panel, wx.ID_ANY, 'ボタン3')

layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(button_1)
layout.Add(button_2)
layout.Add(button_3)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

BoxSizerをセットしているPanelには、わかりやすくするために色を付けています。

縦配置

次は縦方向への配置です。13行目が先程のソースコードからの変更点となります。

import wx

application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, 'テストフレーム', size=(400, 200))

panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour('#AFAFAF')

button_1 = wx.Button(panel, wx.ID_ANY, 'ボタン1')
button_2 = wx.Button(panel, wx.ID_ANY, 'ボタン2')
button_3 = wx.Button(panel, wx.ID_ANY, 'ボタン3')

layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(button_1)
layout.Add(button_2)
layout.Add(button_3)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

フレームサイズとの連動

配置する部品をフレームサイズの大きさに応じて連動させる事も可能で、Addproportion1を指定します。先程のソースコードのようにproportionに何も指定が無いと、デフォルト値として0が適用され、ボタンのサイズはそのまま保持されます。

import wx

application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, 'テストフレーム', size=(400, 200))

panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour('#AFAFAF')

button_1 = wx.Button(panel, wx.ID_ANY, 'ボタン1')
button_2 = wx.Button(panel, wx.ID_ANY, 'ボタン2')
button_3 = wx.Button(panel, wx.ID_ANY, 'ボタン3')

layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(button_1, proportion=1)
layout.Add(button_2, proportion=1)
layout.Add(button_3, proportion=1)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

先程の実行結果と違い、余白が無くなりました。フレームの最大化を行っても、それに応じて適切なサイズへリサイズされます。

配置の詳細制御

配置を細かく制御するにはflagを指定します。GROWは自身に割り当てられている領域を全て使用するようにリサイズされ、SHAPEDは自分自身の縦横比率を維持したままフレームサイズに合わせてリサイズされます。(EXPANDGROWと同じ)また「 | 」を使用して、さらに詳細な配置場所の指定を行う事も可能です。

import wx

application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, 'テストフレーム', size=(570, 200))

panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour('#AFAFAF')

button_1 = wx.Button(panel, wx.ID_ANY, 'ボタン1', size=(80, 30))
button_2 = wx.Button(panel, wx.ID_ANY, 'ボタン2', size=(80, 30))
button_3 = wx.Button(panel, wx.ID_ANY, 'ボタン3', size=(80, 30))
button_4 = wx.Button(panel, wx.ID_ANY, 'ボタン4', size=(80, 30))
button_5 = wx.Button(panel, wx.ID_ANY, 'ボタン5', size=(80, 30))
button_6 = wx.Button(panel, wx.ID_ANY, 'ボタン6', size=(80, 30))
button_7 = wx.Button(panel, wx.ID_ANY, 'ボタン7', size=(80, 30))

layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(button_1, flag=wx.GROW)
layout.Add(button_2, flag=wx.SHAPED)
layout.Add(button_3, flag=wx.SHAPED | wx.ALIGN_TOP)
layout.Add(button_4, flag=wx.SHAPED | wx.ALIGN_BOTTOM)
layout.Add(button_5, flag=wx.SHAPED | wx.ALIGN_CENTER)
layout.Add(button_6, flag=wx.SHAPED | wx.ALIGN_LEFT)
layout.Add(button_7, flag=wx.SHAPED | wx.ALIGN_RIGHT)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

ALIGN_LEFTALIGN_RIGHTはHORIZONTALでは変化がありません。VERTICALにて左右に配置されます。ボタン7が他のボタンに比べて小さいのはフレームのサイズが足りないためで、SHAPEDに従い縦横比率を維持したままリサイズされた結果となります。

余白の指定

borderで余白のピクセル数を指定し、flagで余白部分を指定します。使用出来る余白部分の指定はwx.TOPwx.LEFTwx.RIGHTwx.BOTTOMwx.ALLの5つです。

import wx

application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, 'テストフレーム', size=(300, 200))

panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")

inner_panel_1 = wx.Panel(panel, wx.ID_ANY)
inner_panel_2 = wx.Panel(panel, wx.ID_ANY)
inner_panel_3 = wx.Panel(panel, wx.ID_ANY)

inner_panel_1.SetBackgroundColour('#FF0000')
inner_panel_2.SetBackgroundColour('#00FF00')
inner_panel_3.SetBackgroundColour('#0000FF')

layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(inner_panel_1, proportion=1, flag=wx.EXPAND | wx.TOP,  border=10)
layout.Add(inner_panel_2, proportion=1, flag=wx.EXPAND | wx.LEFT, border=10)
layout.Add(inner_panel_3, proportion=1, flag=wx.EXPAND | wx.ALL,  border=10)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

赤いパネルが上部に余白10px、緑のパネルが左部に余白10px、青パネルが全方位に余白10pxとなります。