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

たいしたことないツールだが完成した。自分にとっては有用なものだと思う。py2exeでパッケージ化までやってみた。

  • 今回おこなったこと
    • wxComboBoxでアルファベットごとのファイル一覧が出るようにした。
    • 一覧からファイルを選択して開けるようにした。
    • 終了をメニューから行えるようにした。
    • 画面左上にアイコンを張り付けた。
    • py2exeでパッケージ化するとき実行モジュールにアイコンをつけた。

起動画面を示す。できることが限られているからシンプルだ。

操作手順としては、まずディレクトリを選択する。

そのディレクトリ内にあるファイルのファイル名のアルファベットに応じてボタンが押せるようになる。押せるときはファイルが存在するとき。

ここでは頭文字pのファイルを選ぶ。ボックス内にファイル名の一覧が。

ファイルを一覧から選んで右のボタンを押すとファイルが開く。ファイルの拡張子で関連付けられたアプリが開いてくれる。自分でアプリを選べないのがなぁー。

  • 今回特に学んだこと
    • 画面左上のアイコンの設置

アイコンを今まで作ったことがなかったが、EDGE
というアプリで作ってみた。.icoファイルとして保存して

ソースコード内で以下のように記述します。

        wx.Frame.__init__(self, id, title="Quick File Selector",
                          size=wx.Size(width, height))
        _icon = wx.Icon('QFS.ico', wx.BITMAP_TYPE_ICO)
        self.SetIcon(_icon)
        mainPan = wx.Panel(self, -1)

2行加えただけで簡単にアイコンを設置できた。http://www.py2exe.org/でアイコンについて調べていたとき方法を見つけた。

    • py2exeでパッケージ化するときにexeファイルにアイコンを付けた。

こうすることで、たいしたことがないプログラムでもそれなりにりっぱに見える。
setup.pyの記述方法はhttp://python.matrix.jp/modules/py2exe.htmlが参考になります。こんな感じのパッケージができる。

以下、今回のソースコード全文です。アイコン画像ファイルを含めてプログラム置場に置きます。

#!/bin/env python
# coding: utf-8
import wx
import webbrowser
import os,sys,time

class MainFrame(wx.Frame):
    def __init__(self, id, title):
        width, height = 400, 250
        wx.Frame.__init__(self, id, title="Quick File Selector",
                          size=wx.Size(width, height))
        _icon = wx.Icon('QFS.ico', wx.BITMAP_TYPE_ICO)
        self.SetIcon(_icon)
        mainPan = wx.Panel(self, -1)
        self.SetMenuBar(self.MakeMenu())
        
        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)
        hsizer05 = 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")
        # open file
        btn02 = wx.Button(mainPan, -1, "Open the file")
        btn02.Bind(wx.EVT_BUTTON, self.OpenFile)

        # combo
        self.cBox01 = wx.ComboBox(mainPan, -1, "File names",
                                  (90,80), (160,-1), [],
                                  wx.CB_DROPDOWN)

        # initial letters, chr(97)='a' and chr(122)='z'
        self.btnAtoZ = []
        self.fileExist = []
        self.fileName = []
        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)
        for i in xrange(ord('z')-ord('a')+1):
            self.btnAtoZ[i].Disable()
            self.btnAtoZ[i].Bind(wx.EVT_BUTTON, self.ShowFileList)
        
        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)

        hsizer05.Add(self.cBox01, 0, wx.ALIGN_LEFT|wx.ALL, 5)
        hsizer05.Add(btn02, 0, wx.ALIGN_LEFT|wx.ALL, 5)

        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)
        vsizer00.Add(hsizer05, 0, wx.ALIGN_LEFT|wx.ALL, 5)

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

    def MakeMenu(self):
        menuBar = wx.MenuBar()        
        self.menu01 = wx.Menu()
        self.menu01.Append(101, "&Quit", "")
        menuBar.Append(self.menu01, "Quit")
        wx.EVT_MENU(self, 101, self.QuitAppl)
        return menuBar

    def QuitAppl(self, event):
        dlg = wx.MessageDialog(self, "Do you really want to quit?",
                               "Quit", style=wx.OK|wx.CANCEL|wx.ICON_QUESTION,
                               pos=(-1,-1))
        answer = dlg.ShowModal()
        if answer == wx.ID_OK:
            self.Close()
        dlg.Destroy
        
    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
        
        # setting condition of buttons
        for i in xrange(ord('z')-ord('a')+1):
            if self.fileExist[i]:
                self.btnAtoZ[i].Enable()
            else:
                self.btnAtoZ[i].Disable()

        # making a list of files
        for i in xrange(ord('a'),ord('z')+1):
            tempList = []
            for k in xrange(len(fileList)):
                if ord(fileList[k][0]) == i:
                    tempList.append(fileList[k])
            self.fileName.append(tempList)   
        
    def SelectDirectory(self, event):
        # obtain file list in selected directory
        dlg = wx.DirDialog(self, message='Please choose a directory')
        ansBtn = dlg.ShowModal()
        if not dlg.GetPath():
            return False
        self.directoryPath = dlg.GetPath()
        self.stTxt01.SetLabel("%s" % self.directoryPath)
        self.CheckFileName()
        return True

    def ShowFileList(self, event):
        buttonLabel = event.GetEventObject().GetLabel()
        fileList = self.fileName[ord(buttonLabel)-ord('a')]
        self.cBox01.Clear()
        for i in fileList:
            self.cBox01.Append(i)
        return True

    def OpenFile(self, event):
        # automatically chosen an application to open
        selectedFile = self.cBox01.GetLabel()
        filePath = os.path.join(self.directoryPath, selectedFile)
        webbrowser.open(filePath)
    
class Application(wx.App):
    def OnInit(self):
        frame = MainFrame(None, -1)
        frame.Show(True)
        self.SetTopWindow(frame)
        return True

def main():
    app = Application(0)
    print "info> current time: %s." % time.ctime(time.time())
    print "info> current directory: %s." % os.getcwd()
    app.MainLoop()

if __name__ == '__main__':
    main()