ComboBox
非常に便利なComboBoxの紹介です。用途に応じて様々な使用方法があり、GUIアプリケーション作成において欠かせない存在となっています。
wxPythonのコンボボックスにはいくつかの種類があります。その内の1つが「シンプル型」で、以下のような特徴があります。
- 選択肢が初めから全て見える
- 他の種類のコンボボックスと比べて配置スペースが大きい
- ユーザーが値を入力出来る
- Windowsのみ使用可
初期化時の引数には(親ウィンドウ、識別子、ラベル、要素配列、コンボボックス種類)の順番で渡しています。
# -*- 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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, u"選択してください", choices=element_array, style=wx.CB_SIMPLE)
layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(combobox_1, flag=wx.GROW)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--

次は「ドロップダウン型」です。特徴は以下の通り。
- 小さい配置スペースに沢山の選択肢を埋め込める
- ユーザーが値を入力出来る
styleには「CB_DROPDOWN」を指定しましょう。
# -*- 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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, u"選択してください", choices=element_array, style=wx.CB_DROPDOWN)
layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(combobox_1, flag=wx.GROW)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
通常時

展開時

最後は「リードオンリー型」です。
- 小さい配置スペースに沢山の選択肢を埋め込める
- ユーザーが値を入力する事は出来ない
styleに「CB_READONLY」を指定しましょう。
# -*- 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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, u"選択してください", choices=element_array, style=wx.CB_READONLY)
layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(combobox_1, flag=wx.GROW)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
通常時

展開時

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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, u"選択してください", choices=element_array, style=wx.CB_SIMPLE | wx.CB_SORT)
layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(combobox_1, flag=wx.GROW)
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")
combobox_1 = wx.ComboBox(panel,wx. ID_ANY, "", choices=element_array, style=wx.CB_SIMPLE)
combobox_2 = wx.ComboBox(panel,wx. ID_ANY, "", choices=element_array, style=wx.CB_SIMPLE)
combobox_1.Append("element_6")
new_array = (u"エレメント1", u"エレメント2", u"エレメント3")
combobox_2.SetItems(new_array)
layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(combobox_1, 1, wx.GROW)
layout.Add(combobox_2, 1, wx.GROW)
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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, "", choices=element_array, style=wx.CB_SIMPLE)
combobox_2 = wx.ComboBox(panel, wx.ID_ANY, "", choices=element_array, style=wx.CB_SIMPLE)
combobox_1.Delete(1)
combobox_2.Clear()
layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(combobox_1, 1, wx.GROW)
layout.Add(combobox_2, 1, wx.GROW)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
「combobox_1」の要素が1つ、「combobox_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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, "", choices=element_array, style=wx.CB_SIMPLE)
print "---------------------------------------"
for i in combobox_1.GetItems():
print i
print "---------------------------------------"
print combobox_1.GetCount()
layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(combobox_1, flag=wx.GROW)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--

--出力結果--
--------------------------------------- element_1 element_2 element_4 element_3 element_5 --------------------------------------- 5
コンボボックスの選択状態の設定は、インデックスで指定する場合には「SetSelection」、要素名で指定する場合では「SetStringSelection」を使用します。 選択値を取得するには「GetSelection」および「GetStringSelection」で、インデックスで取得するか要素名で取得するかで使い分けをします。 なおユーザーによる入力が可能なコンボボックスの場合、入力されたテキスト値は「GetValue」で取得する事が可能です。
# -*- 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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, "", choices=element_array, style=wx.CB_SIMPLE)
combobox_1.SetSelection(3)
combobox_1.SetStringSelection("element_5")
print combobox_1.GetSelection()
print combobox_1.GetStringSelection()
layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(combobox_1, flag=wx.GROW)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
コンボボックスでは1つの要素しか選択出来ないので、後に選択設定した「element_5」が選択されている状態となります。

--出力結果--
4 element_5
コンボボックスへイベントを設定するには「Bind」を使用します。 引数には(イベント種別、イベント発生時に呼び出す関数)の順番で値を渡します。 「combobox_1」のイベント定義はコンボボックスの値が選択されたら、「combobox_2」はテキスト値の入力が行われたら、それぞれ該当の関数の呼び出しが行われます。
# -*- coding: utf-8 -*-
import wx
def combobox_event(event):
obj = event.GetEventObject()
frame.SetStatusText("combobox_1:" + obj.GetStringSelection())
def text_event(event):
obj = event.GetEventObject()
frame.SetStatusText("combobox_2:" + obj.GetValue())
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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, u"選択してください", choices=element_array, style=wx.CB_SIMPLE)
combobox_2 = wx.ComboBox(panel, wx.ID_ANY, u"選択してください", choices=element_array, style=wx.CB_SIMPLE)
combobox_1.Bind(wx.EVT_COMBOBOX, combobox_event)
combobox_2.Bind(wx.EVT_TEXT, text_event)
layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(combobox_1, 1, wx.GROW)
layout.Add(combobox_2, 1, wx.GROW)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
左のコンボボックスは要素を選択すると、右のコンボボックスはテキスト入力を行うと、ステータスバーへ値をセットします。

コンボボックスへ要素を追加する際、画面上へ表示させる文字列とは別に、内部データを保持する事が可能です。「名前」を表示させ「ID」を内部データとして埋め込んでおく、などの使用法が出来るようになるので非常に便利です。サンプルコードでは文字列を埋め込んでいますが、クラスなども埋め込み可能なので是非とも活用しましょう。
# -*- coding: utf-8 -*-
import wx
def combobox_event(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")
combobox_1 = wx.ComboBox(panel, wx.ID_ANY, "", style=wx.CB_SIMPLE)
combobox_1.Append("python-izm", "http://www.python-izm.com/")
combobox_1.Append("google", "http://www.google.co.jp/")
combobox_1.Append("yahoo", "http://www.yahoo.co.jp/")
combobox_1.Append("bing", "http://www.bing.com/")
combobox_1.Bind(wx.EVT_COMBOBOX, combobox_event)
layout = wx.BoxSizer(wx.HORIZONTAL)
layout.Add(combobox_1, flag=wx.GROW)
panel.SetSizer(layout)
frame.Show()
application.MainLoop()
--実行結果--
コンボボックスに表示されているサイト名ではなく、内部で保持していたURLを表示しています。

フリー入力無くしてGUIアプリの明日は無し!
