Python.use(better, Tkinter=”GoF”) # Command
‖記事一覧‖
Python.use(better, Tkinter=”GoF") # Python で学ぶ デザインパターンの世界
《著》森こねこ・小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
α版♪1993/11/25 ● β版♪1995/11/22 ● 第1版♪2003/05/23
概要
Tkinter アプリケーションとして、Python で実現した事例を紹介します。
Tkinter によるオブジェクト指向プログラミングへの扉を開きます。
※ Tcl/Tk で作成した例題を、Tkinter で再構成しました。
事例:step 3
次のコードを実行すると、ウィンドウが現われます。
>>> tips()
## ---------------------------------------- from tkinter import * ## ---------------------------------------- from os import listdir from os.path import join, isdir from functools import reduce from os.path import getsize, getatime, getmtime, getctime from time import ctime ## ---------------------------------------- Composite::Component class Component(object): def __init__(self, path, item): self.path = path self.item = item ## ---------------------------------------- Iterator::Iterator def __iter__(self): pass ## ---------------------------------------- def add_(self, component): pass ## ---------------------------------------- def print(self): for i, e in zip(self.indents(), self.nodes()): print("%s%s"%("+ "*i, e)) ## ---------------------------------------- Composite::Leaf class Leaf(Component): ## ---------------------------------------- Iterator::ConcreteIterator def __iter__(self): return self def __repr__(self): return "#%r"%self.item def __str__(self): return "%s"%self.item ## ---------------------------------------- def items(self): return [self.item] def indents(self, level): return [level] def dirs(self): return [False] def nodes(self): return [self] ## ---------------------------------------- Composite::Composite class Composite(Component): def __init__(self, path, item): super().__init__(path, item) self.children = [] ## ---------------------------------------- Iterator::ConcreteIterator 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 items(self): return reduce(lambda s,e: s+e.items(), 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 nodes(self): return reduce(lambda s,e: s+e.nodes(), self, [self]) ## ---------------------------------------- def add_(self, component): self.children.append(component) ## ---------------------------------------- Composite::Client class TIPS(object): # Client, Aggregate def __init__(self, master, path): self.tree = Composite(path, 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], image=(self.fileImage, self.dirImage)[dir], node=node, ) def createNodes(self): self._createNodes(self.tree, self.path, indent=0) def _createNodes(self, parent, path, indent): 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 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, node ).pack(side=side) Label(frame, text=node.item, font=font).pack(side=side) ## ---------------------------------------- Command::Invoker class Invoker(object): pass class ButtonInvoker(Invoker, Button): def __init__(self, master, image, node): super().__init__( master=master, image=image, command=PanelCommand(node), ) ## ---------------------------------------- Command::Command class Command(object): def __call__(self): pass ## ---------------------------------------- Command::ConcreteCommand class PanelCommand(Command): def __init__(self, node): self.node = node def __call__(self): top = Toplevel() top.title(self.node.item) top.config(padx=16, pady=4) current = join(self.node.path, self.node.item) frame = Frame(master=top) frame.pack() item = "getsize" w = Label(master=frame, text=item) w.pack(side=LEFT) w = Entry(master=frame, width=10) w.pack(side=LEFT) w.insert(END, getsize(current)) frame = Frame(master=top) frame.pack() items = "getatime", "getmtime", "getctime", for i, e in enumerate(items): w = Label(master=frame, text=e) w.grid(row=i, column=0, sticky=E) w = Entry(master=frame, width=22) w.grid(row=i, column=1, sticky=W) w.insert(END, eval("ctime(%s('%s'))"%(e, current))) ## ---------------------------------------- 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
関連記事
- INDEX《Tkinter》
- Let’s GoForward - GoF を反面教師に
- C# Design Patterns 22. The Command Pattern.
Last updated♪2009/09/23