ComboBox

非常に便利なComboBoxの紹介です。用途に応じて様々な使用方法があり、GUIアプリケーション作成において欠かせない存在となっています。

シンプル型

wxPythonのコンボボックスにはいくつかの種類があります。その内の1つがシンプル型で、以下のような特徴があります。

  • 選択肢が初めから全て見える
  • 他の種類のコンボボックスと比べて配置スペースが大きい
  • ユーザーが値を入力出来る
  • Windowsのみ使用可

初期化時の引数には(親ウィンドウ、識別子、ラベル、要素配列、コンボボックス種類)の順番で渡しています。

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')

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)

layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(combobox_1, flag=wx.GROW)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

ドロップダウン型

次はドロップダウン型です。以下のような特徴が持ちます。

  • 小さい配置スペースに沢山の選択肢を埋め込める
  • ユーザーが値を入力出来る

styleにはCB_DROPDOWNを指定しましょう。

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')

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_DROPDOWN)

layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(combobox_1, flag=wx.GROW)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

通常時

展開時

リードオンリー型

最後はリードオンリー型です。

  • 小さい配置スペースに沢山の選択肢を埋め込める
  • ユーザーが値を入力する事は出来ない

styleにCB_READONLYを指定しましょう。

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')

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_READONLY)

layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(combobox_1, flag=wx.GROW)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

通常時

展開時

ソート指定

styleにCB_SORTを追加で指定すると、要素をソートして表示する事が出来ます。

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')

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 | wx.CB_SORT)

layout = wx.BoxSizer(wx.VERTICAL)
layout.Add(combobox_1, flag=wx.GROW)

panel.SetSizer(layout)

frame.Show()
application.MainLoop()

要素の追加

既存のコンボボックスが保持している選択肢に新しく要素を追加する場合はAppend、全ての要素を入れ替える場合はSetItemsを使用します。

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')

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 = ('エレメント1', 'エレメント2', 'エレメント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を使用します。

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')

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を利用します。

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')

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で取得する事が可能です。

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')

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はテキスト値の入力が行われたら、それぞれ該当の関数の呼び出しが行われます。

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, 'テストフレーム', 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, '選択してください', 
                         choices=element_array, style=wx.CB_SIMPLE)
combobox_2 = wx.ComboBox(panel, wx.ID_ANY, '選択してください', 
                         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」を内部データとして埋め込んでおく、などの使用法が出来るようになるので非常に便利です。サンプルコードでは文字列を埋め込んでいますが、クラスなども埋め込み可能なので是非とも活用しましょう。

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, 'テストフレーム', 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('入門編', 'https://www.python-izm.com/introduction/')
combobox_1.Append('基礎編', 'https://www.python-izm.com/basic/')
combobox_1.Append('応用編', 'https://www.python-izm.com/advanced/')
combobox_1.Append('wxPython', 'https://www.python-izm.com/gui/wxpython/')

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を表示しています。