Python 弾丸ツアー #DP: ツリー ... step 3: Composite::Client
Python.use(better); Python 弾丸ツアー #DP: Tkinter/Python 編
>>> ツリー(階層構造)
step 3: Composite::Client
《Python3.1|Jython2.5|IronPython2.6》
《著》小粒ちゃん@湘南組《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/23 ● 第4版♪2010/03/08
step 3: コードの解説
■ Composite::Client
## ---------------------------------------- Composite::Client class TIPS(object): # Client, Aggregate def __init__(self, master, path): self.tree = Composite(path, 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) self.makeTree() def _createNodes(self, parent, path, indent=0): for e in listdir(path): current = join(path, e) if isdir(current): component = Composite(path, e) parent.add_(component) self._createNodes(component, current, indent+1) else: component = Leaf(path, e) parent.add_(component) 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], image=(self.fileImage, self.dirImage)[dir], node=node, ) def createNode(self, master, tab, image, node): 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) ButtonInvoker(frame, image, receiver=node).pack(side=side) Label(frame, text=node.item, font=font ).pack(side=side)
 ̄クラス TIPS では、各種コンポーネントを利用するアプリケーションを規定します。
def makeTree(self): ... self.createNode( master=self.master, tab=tab*indent+(tab_file, tab_folder)[dir], image=(self.fileImage, self.dirImage)[dir], node=node,
 ̄キーワード引数 node= に続いて、ツリーを構成する各ノード node を指定します。
《Point》step2 以前は、
text=self.tail(node),Client が各ノード node を処理する必要がありました。step3 以降は、
node=node,各ノード node に実際の処理を依頼します。そこで、各ノードからパス名(文字列)を得る方法(how)に依存しない、その目的(what)だけを明記します。すると「仕様変更の影響」が少ない、洗練されたコードを記述できます。□
def createNode(self, master, tab, image, node): ... Label(frame, text=tab , font=font ).pack(side=side) ButtonInvoker(frame, image, receiver=node).pack(side=side) Label(frame, text=node.item, font=font ).pack(side=side)
 ̄ButtonInvoker を生成するとともに、イベントに呼応して、処理したい対象 node を指定します。
↑TOP
》作業中です《