Python.use(better, Tkinter=”GoF”) # Composite #2

記事一覧 Python.use(better, Tkinter=”GoF")《Python3.1》
# Python で学ぶ デザインパターンの世界

Composite

《著》森こねこ・小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
α版♪1993/11/25 ● β版♪1995/11/22 ● 第1版♪2003/05/23 ● 第2版♪2006/10/28

概要

Tkinter/Python によるオブジェクト指向プログラミングへの扉を開きます。
※ Tcl/Tk で作成した例題を、Tkinter で再構成しました。

事例:コードの解説

■ Composite::Client
## ---------------------------------------- Composite::Client
class TIPS(object):     # Client

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

    def __init__(self, master, path):
        s = path.split("/")[-1]
        self.tree = Composite(s)        
        self.dirImage  = PhotoImage(file="_image/folder.gif")
        self.fileImage = PhotoImage(file="_image/file.gif")
        self.master = master
        self.path = path

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

    ## ----------------------------------------
    def createNodes(self):
        self._createNodes(self.tree, self.path)

メソッド createNodes は、ディレクトリー self.path の傘下にある階層構造をもとに、ツリー self.tree を生成します。

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

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

        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=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=tail(current),
                    image=self.fileImage,
                    )
  • 関数 listdir を利用して、path の傘下にある各ノード e(ディレクトリー/ファイル)を順にたどりながら、ツリーを構築します。
  • 関数 isdir を利用して、ディレクトリー/ファイルを判定した後で、再帰呼び出し createNode() によって、適切な処理を繰り返します。
    ## ----------------------------------------
    def createNode(self, master, tab, text, image):
        bg   = "yellow"
        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)

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

■ アプリケーションを起動する
## ----------------------------------------
def tips():
    root = Tk()
    root.title("Composite")
    root.config(padx=12, pady=4)

    path = "Python-3.0/Mac/Tools"
    tips = TIPS(root, path)
    tips.createNodes()

    root.mainloop()

path の傘下にある、ディレクトリー/ファイルの階層構造を表現する、ツリーを表示します。

何が問題か

メソッド _createNodes の本体には「重複する記述」があり、そのコードの断片(20行を超える)が大きく、if 文による「条件分岐」があるのも問題です。この問題を解消するために、@ パターンを導入します。

TOP


関連記事

Last updated♪2009/10/30