選択したディレクトリ内のファイルをアルファベットごとに分類して選びやすくするツール(1)

現在、一つのディレクトリ内にソースコードがすべて保存されている状態なのだが、ファイル数が膨大なので、explorerで全体を眺めてもどこにどれがあるのやら、ちょっと探しにくい。そこで、指定したディレクトリ内のファイルを(多少とも)簡単に選択して開くツールをwxPythonで作ろうと思う。

  • 動作イメージ
    • ツールの画面には、'a'から'z'までのボタンが並んでいる(図1)。
    • 分類したいソースコードが保存されているディレクトリをまず指定する。
    • ファイルが存在すれば、ファイルの頭文字に対応するアルファベットのボタンが押せる状態になる。
    • それらのボタンのどれかを押すと、頭文字がそのアルファベットであるファイルのリストがずらっと表示される。
    • 表示されたリストの中からファイル名を選んで、そのファイルを開ける。

図1のように、外側だけ作った。まだ途中だけど。

図1:起動画面(できたところまで)

ソースの一部は以下の通り。

class MainFrame(wx.Frame):
    def __init__(self, id, title):
        width, height = 530, 350
        wx.Frame.__init__(self, id, title="Making File List",
                          size=wx.Size(width, height))
        mainPan = wx.Panel(self, -1)
        vsizer00 = wx.BoxSizer(wx.VERTICAL)
        vsizer01 = wx.BoxSizer(wx.VERTICAL)
        hsizer01 = wx.BoxSizer(wx.HORIZONTAL)
        hsizer02 = wx.BoxSizer(wx.HORIZONTAL)
        hsizer03 = wx.BoxSizer(wx.HORIZONTAL)
        hsizer04 = wx.BoxSizer(wx.HORIZONTAL)

        # select directory
        btn01 = wx.Button(mainPan, -1, "Select a directory")
        btn01.Bind(wx.EVT_BUTTON, self.SelectDirectory)
        self.stTxt01 = wx.StaticText(mainPan, -1, "Directory Path")

        # initial letters, chr(97)='a' and chr(122)='z'
        self.btnAtoZ = []
        self.fileExist = []
        for i in xrange(ord('a'), ord('z')+1):
            letter = chr(i)
            self.btnAtoZ.append(wx.Button(mainPan, size=(20,-1), label=letter))
            self.fileExist.append(False)
        
        hsizer01.Add(btn01, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        hsizer01.Add(self.stTxt01, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        
        for k in xrange(0,10):
            hsizer02.Add(self.btnAtoZ[k], 0, wx.ALIGN_LEFT|wx.ALL, 2)
        for k in xrange(10,20):
            hsizer03.Add(self.btnAtoZ[k], 0, wx.ALIGN_LEFT|wx.ALL, 2)
        for k in xrange(20,26):
            hsizer04.Add(self.btnAtoZ[k], 0, wx.ALIGN_LEFT|wx.ALL, 2)

        vsizer00.Add(hsizer01, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        vsizer01.Add(hsizer02, 0, wx.ALIGN_LEFT|wx.ALL, 1)
        vsizer01.Add(hsizer03, 0, wx.ALIGN_LEFT|wx.ALL, 1)
        vsizer01.Add(hsizer04, 0, wx.ALIGN_LEFT|wx.ALL, 1)
        vsizer00.Add(vsizer01, 0, wx.ALIGN_LEFT|wx.ALL, 5)

        mainPan.SetSizer(vsizer00)
        vsizer00.Fit(mainPan)

'a'から'z'までのボタン(wx.Button)をリストとして扱い、サイザーで並べる。ファイル名が大文字で始まることは想定していない(とりあえずはいいけど、不便な状況になるかも)。

    def CheckFileName(self):
        fileList = os.listdir(self.directoryPath)
        for i in xrange(len(fileList)):
            if ord(fileList[i][0]) >= ord('a') and\
            ord(fileList[i][0]) <= ord('z'):
                self.fileExist[ord(fileList[i][0])-ord('a')] = True
        
        # control buttons
        for i in xrange(ord('z')-ord('a')+1):
            if self.fileExist[i]:
                self.btnAtoZ[i].Enable()
            else:
                self.btnAtoZ[i].Disable()

ここでは、ファイルの一覧を取り出し(os.listdir)、ファイル名の頭文字に従ってボタンを押せない状態にする処理を行う。その結果、図2のようになる。ここでは'a'から始まるファイルしかない場合。

図2:テスト結果('a'のボタンしか押せなくなった)

ここまではよい。