Pythonでコマンドラインランチャを作ろう!第四回−パスファイルからの読み出し

前置き

四回目ですね。
今回は、テキストファイルに書き込んだパスを読み取り、それをリストボックスに表示するところまでやります。
今までは、craftlaunchとfenrir両方に共通することをやってきたわけですが、今回はfenrir型(こんな言葉あるのか知りませんが)に絞ってやるわけですにゃ。craftlaunch型(?)については、この後にやります。

準備

とりあえず、パスが羅列されたテキストファイルを作成するところから始めましょう。fenrirのpathファイルを流用して、けふんけふん!( >Д<)メモ帳かなにか適当なエディタで次みたいなテキストファイルを作ります。

C:\Program Files\Opera\Opera.exe
D:\bin\kiki\kiki.exe
D:\bin\afxw\AFXW.EXE

当然、ここに書くパスは実在するパスをコピペして書き込んでください。実行ファイルのパスを適当にとってきて、コピペという感じで。パスが何でどう取得したらいいかわからない場合はグーグルさんにでも聞いてください。
次に、どこに保存するかですね。今まで私たちが作ってきたランチャと同じフォルダに、新しいフォルダ"data"フォルダを作りましょう。その中に、先のファイルを"path.txt"という名前で保存します。

命名

今までこのランチャに名前つけていませんでした。呼ぶのにめんどいので、名前つけます。
クラスタイトルがMyExcalibur(ぼくのエクスカリバー)だったりするのをみてもわかるように、ここで書いているのは僕が、自分用のコマンドラインランチャ=エクスカリバーを作る過程で学んだことです。だから、ここでコードを書いているまだ小さくて発育途中のコマンドラインランチャと、僕の一皮むけてぼちぼち大きく立派に育ったエクスカリバーとは、似ているけれど別物といったら別物。姉妹みたいなものですかね。お姉ちゃんの後ろを追って、まねをしたりして徐々に育ってきている可愛い妹、という感じでしょうか。かがみ「つかさ帰るわよ!」 つかさ「あー待ってよおねえちゃーん」
みんなにとってはどうでもいいことかもしれませんが、単純に僕がファイルとして区別するときに紛らわしくて困るということから、ここで作っているコマンドラインランチャに名前を付けます。あ、別にみんなが違うファイル名で保存しているんだったらべつにそれでもいいですよ!?
ということで、
命名!エクスカリパー
文字が小さいままだとエクスカリバーと間違われかねないので、おおきくしてみました。
英語にしたらExcalipurです!略称はExpねo(^-^)o

このとびらのうらでずっと待っていたぞ!

来なかったらどうしようかと不安になっていたところだ!

いくぞ!

今後からエクスカリパーと呼びます。ここに書いたソースを試すときには、ビックブリッジの死闘を口ずさみながらお試しください。じょうとうだぜ!このギルガメッシュ様が・・・・・・たおせるかな?!……クルル!お前のおじいちゃん・・・・・・強かったぜ!


大まかな順序

テキストファイルから、各行を読み取り、それをリスト化すれば今回の目的は達成できる訳ですね。

手順としては、

  1. ファイルを開く
  2. 内容を取り出す
  3. ファイルを閉じる

です。

では具体的に。パスファイルから読み出して、それをリストに付け足すには次みたくすればいいわけですね。

        f = open("data/path.txt", "r")
        for x in f.readlines():
            self.List.append(x.strip())
        f.close()

一行目で、リードオンリーで先ほど作ったテキストファイルを読み込んでいます。"data/path.txt"が、先に作ったテキストファイルを表しているわけですね。
そして、二、三行目でそれをself.Listに追加しています。f.readlines()というのは、各行をリスト化したものですが、改行文字などの関係でそれを取り除く必要があります。そこで、そのそれぞれの要素に、strip()をかけて空白を取り除いてリストに入れるということを行っているわけです。
で、四行目で閉じると。

上の成果をふまえ、OnInitは次のようになります。

    def OnInit(self):
        PATH_FILE = "data/path.txt"
        self.List = []
        f = open(PATH_FILE, "r")
        for x in f.readlines():
            self.List.append(x.strip())
        f.close()  
        Frm = wx.Frame(None, -1, "Excalipur", size=(400,48),pos=(400,400))
        self.TxtCtr = wx.TextCtrl(Frm, -1)
        self.lbFrame = wx.Frame(None, 0, "wxPython", size=(420,200),pos=(400,448),style=wx.DOUBLE_BORDER)
        self.LBox = wx.ListBox(self.lbFrame, -1, choices = self.List, size=(415,200))
        Frm.Show()
        self.lbFrame.Show()
        self.TxtCtr.SetFocus()
        return 1

exp01

いつものように、全体のコードを。

import wx

class MyExcalibur(wx.PySimpleApp):
    
    def OnInit(self):
        PATH_FILE = "data/path.txt"
        self.List = []
        f = open(PATH_FILE, "r")
        for x in f.readlines():
            self.List.append(x.strip())
        f.close()
        Frm = wx.Frame(None, -1, "Excalipur", size=(400,48),pos=(400,400))
        self.TxtCtr = wx.TextCtrl(Frm, -1)
        self.TxtCtr.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        self.TxtCtr.Bind(wx.EVT_TEXT,self.OnText)
        self.lbFrame = wx.Frame(None, 0, "wxPython", size=(420,200),pos=(400,448),style=wx.DOUBLE_BORDER)
        self.LBox = wx.ListBox(self.lbFrame, -1, choices = self.List, size=(415,200))
        Frm.Show()
        self.lbFrame.Show()
        self.TxtCtr.SetFocus()
        return 1


    def OnKeyDown(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()

    def OnText(self,event):
        get_word = self.TxtCtr.GetValue()
        get_list = self.SearchWord(get_word)
        self.LBox.Set(get_list)
        event.Skip()

    def SearchWord(self,word):
        new_list = []
        for line in self.List:
            if word in line:
                new_list.append(line)
        return new_list


app = MyExcalibur()
app.MainLoop()