ListBox
複数の要素の中から1つ、もしくは複数を選択出来るListBoxのサンプルです。単純なデータの表示に向いており、複数の要素を目視しながら項目を選択出来ます。
単一選択のリストボックスが最も基本的な形となります。引数「choices」に表示する要素を渡し、「style」に「LB_SINGLE」を指定する事によって単一選択のリストが初期化されます。ただしデフォルトのスタイルが単一選択リストなので、特に明示せずとも単一の選択リストとなります。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
#listbox = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
listbox = wx.ListBox(panel, wx.ID_ANY, choices=element_array, style=wx.LB_SINGLE)
layout = wx.GridSizer(1, 1)
layout.Add(listbox, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
常に1つの要素しか選択出来ません。もう1つを選択すると、既に選択されていた要素は選択解除されます。

「style」に「LB_MULTIPLE」を指定すると、要素を複数選択出来るようになります。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
listbox = wx.ListBox(panel, wx.ID_ANY, choices=element_array, style=wx.LB_MULTIPLE)
layout = wx.GridSizer(1, 1)
layout.Add(listbox, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
クリックをする度に要素が選択されます。選択状態の要素を再度クリックすると、選択状態が解除されます。

「LB_EXTENDED」でも複数の要素を選択出来ます。このスタイルは「Shift」キーや「Ctrl」キーと組み合わせて選択をする事で、複数の要素の選択が可能です。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
listbox = wx.ListBox(panel, wx.ID_ANY, choices=element_array, style=wx.LB_EXTENDED)
layout = wx.GridSizer(1, 1)
layout.Add(listbox, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
単純にクリックをしただけでは複数の要素は選択されません。特殊キーと組み合わせて選択をしてみましょう。

要素数が多い場合、極端に要素名が長い場合など、リストボックスの表示領域に収まりきらないケースがあるかと思います。そういった時はスクロールバーを設定し、全要素をきちんと確認出来る様にしておく必要があります。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(400,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5", "long_long__element")
listbox_1 = wx.ListBox(panel, wx.ID_ANY, size=(100,200), choices=element_array, style=wx.LB_HSCROLL)
listbox_2 = wx.ListBox(panel, wx.ID_ANY, size=(100,200), choices=element_array, style=wx.LB_ALWAYS_SB)
listbox_3 = wx.ListBox(panel, wx.ID_ANY, size=(100,200), choices=element_array, style=wx.LB_NEEDED_SB)
layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(listbox_1, flag=wx.GROW | wx.ALL, border=3)
layout.Add(listbox_2, flag=wx.GROW | wx.ALL, border=3)
layout.Add(listbox_3, flag=wx.GROW | wx.ALL, border=3)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
「LB_HSCROLL」 リストボックスの横幅に収まりきらなかった場合に限り横スクロールを表示
「LB_ALWAYS_SB」要素数に関わらず常時縦スクロールを表示
「LB_NEEDED_SB」リストボックスの縦幅に収まりきらなかった場合に限り縦スクロールを表示

styleに「CB_SORT」を追加で指定すると、要素をソートして表示する事が出来ます。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
listbox = wx.ListBox(panel, wx.ID_ANY, choices=element_array, style=wx.LB_SORT)
layout = wx.GridSizer(1, 1)
layout.Add(listbox, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
ソート指定無し

ソート指定有り

今までに紹介したスタイルを複数指定するには「 | 」を使用します。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("1", "2", "4", "3", "5", "6", "8", "7", "9")
listbox = wx.ListBox(panel, wx.ID_ANY, choices=element_array, style=wx.LB_EXTENDED | wx.LB_HSCROLL | wx.LB_NEEDED_SB | wx.LB_SORT)
layout = wx.GridSizer(1, 1)
layout.Add(listbox, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
特殊キーによる複数選択、横スクロールバー有り、縦スクロールバー有り、ソート指定が設定されています。

リストボックスが保持している既存の選択肢に、新しく要素を追加する場合は「Append」、全ての要素を入れ替える場合は「SetItems」を使用します。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
listbox_1 = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
listbox_2 = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
listbox_1.Append("element_6")
new_array = ("エレメント1", "エレメント2", "エレメント3")
listbox_2.SetItems(new_array)
layout = wx.GridSizer(1, 2)
layout.Add(listbox_1, flag=wx.GROW | wx.ALL, border=10)
layout.Add(listbox_2, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
それぞれのリストボックスの値が変更されています。

リストボックスが保持している既存の選択肢から、指定の要素を削除する場合は「Delete」を(引数は削除したい要素のインデックス)、全ての要素を削除する場合は「Clear」を使用します。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
listbox_1 = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
listbox_2 = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
listbox_1.Delete(1)
listbox_2.Clear()
layout = wx.GridSizer(1, 2)
layout.Add(listbox_1, flag=wx.GROW | wx.ALL, border=10)
layout.Add(listbox_2, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
「listbox_1」の要素が1つ、「listbox_2」の全要素が削除されています。

リストボックスが保持している全要素を取得するには「GetItems」を、要素数を取得する場合には「GetCount」を利用します。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
listbox = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
print "---------------------------------------"
for i in listbox.GetItems():
print i
print "---------------------------------------"
print listbox.GetCount()
layout = wx.GridSizer(1, 1)
layout.Add(listbox, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--

--出力結果--
--------------------------------------- element_1 element_2 element_4 element_3 element_5 --------------------------------------- 5
リストボックスの選択状態の設定は、インデックスで指定する場合に「SetSelection」、要素名で指定する場合では「SetStringSelection」を使用します。 選択値を取得する際は、単一選択のリストボックスの場合「GetSelection」、複数選択リストボックスの場合は「GetSelections」で選択されている要素のインデックス値が返ってきます。
# -*- coding: utf-8 -*-
import wx
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
listbox_1 = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
listbox_2 = wx.ListBox(panel, wx.ID_ANY, choices=element_array, style=wx.LB_EXTENDED)
listbox_1.SetSelection(3)
listbox_1.SetStringSelection("element_5")
print listbox_1.GetSelection()
listbox_2.SetSelection(3)
listbox_2.SetStringSelection("element_5")
print listbox_2.GetSelections()
layout = wx.GridSizer(1, 2)
layout.Add(listbox_1, flag=wx.GROW | wx.ALL, border=10)
layout.Add(listbox_2, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
listbox_1では1つの要素しか選択出来ないので、後に選択設定した「element_5」が選択されている状態となります。

--出力結果--
4 (3, 4)
リストボックスへイベントを設定するには「Bind」を使用します。 引数は(イベント種別、イベント発生時に呼び出す関数)の順番で値を渡します。 「listbox_1」のイベント定義はリストボックスの要素が選択されたら、「listbox_2」は要素がダブルクリックされたら、それぞれ該当の関数の呼び出しが行われます。
# -*- coding: utf-8 -*-
import wx
def listbox_select(event):
obj = event.GetEventObject()
frame.SetStatusText("listbox_1:" + obj.GetStringSelection())
def listbox_double_click(event):
obj = event.GetEventObject()
frame.SetStatusText("listbox_2:" + obj.GetStringSelection())
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
frame.CreateStatusBar()
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
element_array = ("element_1", "element_2", "element_4", "element_3", "element_5")
listbox_1 = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
listbox_2 = wx.ListBox(panel, wx.ID_ANY, choices=element_array)
listbox_1.Bind(wx.EVT_LISTBOX, listbox_select)
listbox_2.Bind(wx.EVT_LISTBOX_DCLICK, listbox_double_click)
layout = wx.GridSizer(1, 2)
layout.Add(listbox_1, flag=wx.GROW | wx.ALL, border=10)
layout.Add(listbox_2, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
左のリストボックスは要素を選択すると、右のリストボックスは要素をダブルクリックするとステータスバーへ値をセットします。

リストボックスへ要素を追加する際、画面上へ表示させる文字列とは別に、内部データを保持する事が可能です。「名前」を表示させ「ID」を内部データとして埋め込んでおく、などの使用法が出来るようになるので非常に便利です。サンプルコードでは文字列を埋め込んでいますが、クラスなども埋め込み可能なので是非とも活用しましょう。
# -*- coding: utf-8 -*-
import wx
def listbox_select(event):
obj = event.GetEventObject()
frame.SetStatusText(obj.GetClientData(obj.GetSelection()))
application = wx.App()
frame = wx.Frame(None, wx.ID_ANY, u"テストフレーム", size=(300,200))
frame.CreateStatusBar()
panel = wx.Panel(frame, wx.ID_ANY)
panel.SetBackgroundColour("#AFAFAF")
listbox = wx.ListBox(panel, wx.ID_ANY)
listbox.Append("python-izm", "http://www.python-izm.com/")
listbox.Append("google", "http://www.google.co.jp/")
listbox.Append("yahoo", "http://www.yahoo.co.jp/")
listbox.Append("bing", "http://www.bing.com/")
listbox.Bind(wx.EVT_LISTBOX, listbox_select)
layout = wx.GridSizer(1, 1)
layout.Add(listbox, flag=wx.GROW | wx.ALL, border=10)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
リストボックスに表示されているサイト名ではなく、内部で保持していたURLを表示しています。

