Python 弾丸ツアー #DP: ツリー ... step 1: Composite::Client

OOPデザインパターンリファクタリング

Python.use(better); Python 弾丸ツアー #DP: Tkinter/Python
>>> ツリー(階層構造)
step 1: Composite::Client
《Python3.1|Jython2.5|IronPython2.6》

《著》小粒ちゃん@湘南組《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/23 ● 第4版♪2010/03/08

step 1: Composite::Client

■ Composite::Client
## ---------------------------------------- Composite::Client
class TIPS(object):     # Client
    def __init__(self, master, path):
        self.tree = Composite(self.tail(path))
        image_path = "../_image"
        self.dirImage  = PhotoImage(file="%s/folder.gif"%image_path)
        self.fileImage = PhotoImage(file="%s/file.gif"  %image_path)
        self.master = master
        self.path = path

    def tail(self, path):
        return path.split("/")[-1]

    def createNodes(self):
        self.createNodes_(self.tree, self.path)

    def createNodes_(self, parent, path, indent=0):
        tab        = "    "
        tab_folder = "  + "
        tab_file   = "  . "

        for e in listdir(path):
            current = join(path, e)
            if isdir(current):
                component = Composite(e)
                parent.add_(component)
                self.createNode(
                    master=self.master,
                    tab=tab*(indent)+tab_folder,
                    text=self.tail(current),
                    image=self.dirImage,
                    )
                self.createNodes_(component, current, indent+1)
            else:
                component = Leaf(e)
                parent.add_(component)
                self.createNode(
                    master=self.master,
                    tab=tab*(indent)+tab_file,
                    text=self.tail(current),
                    image=self.fileImage,
                    )

    def createNode(self, master, tab, text, image):
        bg   = "aliceblue"      # "aliceblue,yellow,cyan"
        font = "courier 12"
        side = LEFT

        frame = Frame(master)
        frame.config(bg=bg)
        frame.pack(anchor=W)
        Label (frame, text=tab , font=font).pack(side=side)
        Button(frame, image=image)         .pack(side=side)
        Label (frame, text=text, font=font).pack(side=side)

 ̄クラス TIPS では、Component を利用するアプリケーションを規定します。□

    def __init__(self, master, path):
        self.tree = Composite(self.tail(path))
        ...

 ̄メソッド __init__ では、さまざまなインスタンス属性を初期設定します。

  • インスタンス属性 self.tree は、頂点に位置するツリー Composite を保持します。
    def createNodes(self):
        self.createNodes_(self.tree, self.path)

 ̄フォルダー self.path を頂点とする階層構造に沿って、ツリー self.tree を生成します。

    def createNodes_(self, parent, path, indent=0):
        ...
        for e in listdir(path):
            current = join(path, e)

 ̄関数 listdir を利用して、path を頂点とする各ノード e を順にたどりながら、ツリーを構築します。さらに、関数 isdir を利用して、フォルダー/ファイルを判定します。このとき、処理の対象になるノード current が、

            if isdir(current):
                component = Composite(e)
                parent.add_(component)    # (@.@)
                self.createNode(...
                self.createNodes_(component, current, indent+1)

フォルダーなら、親ツリー parent の傘下に、フォルダー Composite を追加 add_ するとともに、新たなノードを生成 createNode します。再帰呼び出し createNodes_() によって、適切な処理を繰り返します。また、

            else:
                component = Leaf(e)
                parent.add_(component)    # (@.@)
                self.createNode(...

ファイルなら、親ツリー parent の傘下に、ファイル Leaf を追加 add_ するとともに、新たなノードを生成 createNode します。

    def createNode(self, master, tab, text, image):
        ...
        frame = Frame(master)
        Label (frame, text=tab , font=font).pack(side=side)
        Button(frame, image=image)         .pack(side=side)
        Label (frame, text=text, font=font).pack(side=side)

Tkinterコンポーネント(Label/Button)を利用して、ツリーの各ノードを構築します。□

《Point》入れ子になった階層構造の取扱いには、再帰呼び出しを利用します。ここでは、メソッド createNodes を実現するのに、メソッド createNodes_ を利用しています。そして、メソッド createNodes_ を実現するのに、メソッド createNodes_ 自身を利用しています。すると、フォルダー内に他のフォルダーが含まれるときも、適切に対処できます。□

TOP
》作業中です《