wxPythonでAA管理ツールを作ろう!第二回 ListBoxの操作

あいさつ

つかさです。
今回は、前回作ったGuiにリストをセットし、操作してみます。

やっていることは、Pythonでコマンドラインランチャを作ろう!第二回イベント編とほぼ同じです。そちらもあわせて参考にしてください。

リストの作成

  • AAlist02.py
import wx

List = ["tukasa","konata","kagami","miwiki","yutaka",
        "minami","misao","ayano","hiyori","Martin"]

class MyTxtFrm(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id)
        self.TxtCtr = wx.TextCtrl(self, -1)
        self.LBox = wx.ListBox(self, -1, choices = List)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.TxtCtr, 0, wx.EXPAND)
        self.sizer.Add(self.LBox, 1, wx.EXPAND)
        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        self.sizer.Fit(self)

class MyApp(wx.PySimpleApp): 
    def OnInit(self):
        self.TxtFrm = MyTxtFrm(None, -1)
        self.TxtFrm.SetSize( (180, 200) )
        self.TxtFrm.Show()
        self.TxtFrm.TxtCtr.SetFocus()
        return 1

app = MyApp()
app.MainLoop()

前回から変更したのは二行。Listの追加と、それをListBoxの引数に追加したことです。
まずはリストについて。見たままですね。

List = ["tukasa","konata","kagami","miwiki","yutaka",
        "minami","misao","ayano","hiyori","Martin"]

これをListBoxにセットするため、ListBoxの引数にchoices = Listを追加します。

self.LBox = wx.ListBox(self, -1, choices = List)

リストボックスをエディットボックスから操作

AAlist02.pyからの変更は二点です。
関数OnKeyCharを付け加え、初期化メソッドに一文付け加えています。

  • AAlist03.py
import wx

List = ["tukasa","konata","kagami","miwiki","yutaka",
        "minami","misao","ayano","hiyori","Martin"]

class MyTxtFrm(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id)
        self.TxtCtr = wx.TextCtrl(self, -1)
        self.LBox = wx.ListBox(self, -1, choices = List)
        self.TxtCtr.Bind(wx.EVT_KEY_DOWN, self.OnKeyChar)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.TxtCtr, 0, wx.EXPAND)
        self.sizer.Add(self.LBox, 1, wx.EXPAND)
        self.SetSizer(self.sizer)
        self.SetAutoLayout(1)
        self.sizer.Fit(self)


    def OnKeyChar(self,event):
        key = event.GetKeyCode()
        if key ==  wx.WXK_ESCAPE:
            wx.Exit()
        elif key == wx.WXK_UP:
            count = self.LBox.GetCount()
            next = self.LBox.GetSelection() - 1
            if next >=  0:
                self.LBox.SetSelection(next)
            else: self.LBox.SetSelection(count - 1)
        elif key == wx.WXK_DOWN:
            count = self.LBox.GetCount()
            next = self.LBox.GetSelection() + 1
            if next < count:
                self.LBox.SetSelection(next)
            else: self.LBox.SetSelection(0)
        else: event.Skip()

class MyApp(wx.PySimpleApp): 
    def OnInit(self):
        self.TxtFrm = MyTxtFrm(None, -1)
        self.TxtFrm.SetSize( (180, 200) )
        self.TxtFrm.Show()
        self.TxtFrm.TxtCtr.SetFocus()
        return 1

app = MyApp()
app.MainLoop()


イベント用の関数OnKeyCharを作成

ついで、エディットボックスからリストボックスを操作できるようにします。
文字を入力してインクリメンタルサーチをし、絞り込むということを後々するため、フォーカスはずっとエディットボックスになければならない。そこで、エディットボックスでキーを操作すればそれでリストボックスで動作するように、設定する必要があります。
キーが押されたときに発生させるためのイベント用の関数OnKeyCharを作成します。

    def OnKeyChar(self,event):
        key = event.GetKeyCode()
        if key ==  wx.WXK_ESCAPE:
            wx.Exit()
        elif key == wx.WXK_UP:
            count = self.LBox.GetCount()
            next = self.LBox.GetSelection() - 1
            if next >=  0:
                self.LBox.SetSelection(next)
            else: self.LBox.SetSelection(count - 1)
        elif key == wx.WXK_DOWN:
            count = self.LBox.GetCount()
            next = self.LBox.GetSelection() + 1
            if next < count:
                self.LBox.SetSelection(next)
            else: self.LBox.SetSelection(0)
        else: event.Skip()

event.GetKeyCode()で打たれたキーを受け取り、そのキーによって

  • Escape
  • カーソル上
  • カーソル下

の三つに分岐させています。

  • キーがエスケープキー(wx.WXK_ESCAPE)だったら、wx.Exit()で終了させます。
  • キーがカーソル上(wx.WXK_UP)だったら、GetSelection()で現在リストボックスで選択しているのは上から何番目かを受け取り、その一つ上を、SetSelection()でリストボックスにセットしてます。
  • カーソル下(wx.WXK_DOWN)だったら、GetSelection()で現在リストボックスで選択している位置を受け取り、その一つ下を、SetSelection()でリストボックスにセットしてます。

GetCount()でリストボックスにあるアイテムの総数を受け取ったり、ifで条件分岐をしたりしているのは、端まで行ったときにループさせるためです。

GUIと関数を結びつける

ついで、これをエディットボックスと結びつけます。class MyTxtFrmの初期化メソッド__init__に、次の一文を付け加えます。

self.TxtCtr.Bind(wx.EVT_KEY_DOWN, self.OnKeyChar)

これで、エディットボックスで上下カーソルを押すことで、リストボックスの選択カーソルを移動できるようになりました。