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

記事一覧 Python.use(better)《Python3.1》

Iterator

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

概要

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

事例:step 2

次のコードを実行すると、ウィンドウが現われます。

>>> tips()


## ----------------------------------------
from tkinter import *

## ----------------------------------------
from os import listdir
from os.path import join, isdir
from functools import reduce

## ---------------------------------------- Composite::Component
class Component(object):

    def __init__(self, item):
        self.item = item

    ## ----------------------------------------
    def print(self):
        for i, e in zip(self.indents(), self.nodes()):
            print("%s%s"%("+  "*i, e))

## ---------------------------------------- Composite::Leaf
class Leaf(Component):

    def __iter__(self):
        return self

    def __repr__(self):
        return "#%r"%self.item

    def __str__(self):
        return "%s"%self.item

    ## ----------------------------------------
    def nodes(self):
        return [self.item]

    def indents(self, level):
        return [level]

    def dirs(self):
        return [False]

## ---------------------------------------- Composite::Composite
class Composite(Component):

    def __init__(self, item):
        super().__init__(item)
        self.children = []

    def __iter__(self):
        for e in self.children:
            yield e

    def __repr__(self):
        return "%s(#%s: [%s])"%(
            self.__class__.__name__,
            self.item,
            ",".join([str(e) for e in self]),
            )

    def __str__(self):
        return "\n".join([self.item]+[str(e) for e in self])

    ## ----------------------------------------
    def nodes(self):
        return reduce(lambda s,e: s+e.nodes(),
            self, [self.item])

    def indents(self, level=0):
        return reduce(lambda s,e: s+e.indents(level+1),
            self, [level])

    def dirs(self):
        return reduce(lambda s,e: s+e.dirs(),
            self, [True])

    ## ----------------------------------------
    def add_(self, component):
        self.children.append(component)

## ---------------------------------------- Composite::Client
class TIPS(object):     # Client, Aggregate

    def __init__(self, master, path):
        self.tree = Composite(self.tail(path))        
        self.dirImage  = PhotoImage(file="_image/folder.gif")
        self.fileImage = PhotoImage(file="_image/file.gif")
        self.master = master
        self.path = path

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

    ## ----------------------------------------
    def makeTree(self):
        tab        = "    "
        tab_folder = "  + "
        tab_file   = "  . "

        T = self.tree
        for indent, dir, node in zip(
            T.indents(), T.dirs(), T.nodes()
        ):
            self.createNode(
                master=self.master,
                tab=tab*indent+(tab_file, tab_folder)[dir],
                text=self.tail(node),
                image=(self.fileImage, self.dirImage)[dir],
                )

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

    def _createNodes(self, parent, path, indent=0):
        for e in listdir(path):
            current = join(path, e)
            if isdir(current):
                component = Composite(e)
                parent.add_(component)
                self._createNodes(component, current, indent+1)
            else:
                component = Leaf(e)
                parent.add_(component)

    ## ----------------------------------------
    def createNode(self, master, tab, text, image):
        bg   = "aliceblue"
        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)

## ----------------------------------------
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()
    tips.makeTree()

    root.mainloop()

TOP