Python デザインパターン サンプルコード Command
結城 浩「Java言語で学ぶデザインパターン入門」をPython化
Python3(3.11)で動くソースコード(.pyファイル .ipynbファイル)あります
「anaconda3」on .py「PyCharm」.ipynb「Jupyter Notebook」
(2023-11-19)Python3.11で動作確認済み
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys from abc import ABCMeta, abstractmethod import tkinter as Tk class Command(metaclass=ABCMeta): def execute(): pass class MacroCommand(Command): # 命令の集合 # 実行 def execute(): pass # 追加 def append(cmd): pass # 最後の命令を削除 def undo(): pass # 全部削除 def clear(): pass class DrawCommand(Command): def DrawCommand(drawable, position): self.drawable = drawable self.position = position # 実行 def execute(): drawable.draw(position.x, position.y) class Drawable(metaclass=ABCMeta): def draw(x, y): pass class DrawCanvas(Tk.Canvas, Drawable): draw_canvas = None def __init__(self, x0, y0, x1, y1, **key): self.id = self.draw_canvas.create_line(x0, y0, x1, y1, **key) self.draw_canvas.bind('<ButtonPress-3>', self.mouse_right_click) self.draw_canvas.bind('<B3-Motion>', self.mouse_drag) # 消しゴム def mouse_right_click(self, event): self.sx = event.x self.sy = event.y def mouse_drag(self, event): self.draw_canvas.create_line(self.sx, self.sy, event.x, event.y, fill='white', width=10) self.sx = event.x self.sy = event.y class MainFrame(Tk.Frame): def __init__(self, master=None): Tk.Frame.__init__(self, master) self.master.title("Command Pattern Sample") # ウィンドウはメインルーチンで作られている #window = Tk.Tk() # クリアボタン self.clear_button = Tk.Button( self, text = "clear", command=self.clear_click) self.clear_button.pack(side = Tk.TOP) # キャンバス(別のクラス) self.canvas = Tk.Canvas( self, bg = "white", width = 500, height = 500) self.canvas.pack() # お絵かきのためのマウス操作のイベントドリブン self.canvas.bind('<ButtonPress-1>', self.mouse_left_click) self.canvas.bind('<B1-Motion>', self.mouse_drag) # 調合した色のサンプル self.label = Tk.Label(self, text='Selected', fg='#ffffff', width=15) self.label.pack() # 色の調合のためのスケール self.R_scale = Tk.Scale( self, label='Red', orient=Tk.HORIZONTAL, from_=0, to=255, length=300, resolution=1, command=self.palette) self.R_scale.set(255) self.R_scale.pack() self.G_scale = Tk.Scale( self, label='Green', orient=Tk.HORIZONTAL, from_=0, to=255, length=300, resolution=1, command=self.palette) self.G_scale.pack() self.B_scale = Tk.Scale( self, label='Blue', orient=Tk.HORIZONTAL, from_=0, to=255, length=300, resolution=1, command=self.palette) self.B_scale.pack() # 線の太さを選ぶ self.line_width = Tk.Scale( self, label='Line Width', from_=1, to=15, orient=Tk.HORIZONTAL) self.line_width.set(5) self.line_width.pack() # コンストラクタ終 # 左ボタンクリック def mouse_left_click(self, event): self.sx = event.x self.sy = event.y # マウスドラッグ def mouse_drag(self, event): DrawCanvas.draw_canvas=self.canvas DrawCanvas(self.sx, self.sy, event.x, event.y, fill=self.select_color, width=self.line_width.get()) self.sx = event.x self.sy = event.y # 色の調合 def palette(self, event): self.select_color = '#%02x%02x%02x' % ( self.R_scale.get(), self.G_scale.get(), self.B_scale.get()) self.label.configure(bg=self.select_color) def clear_click(self): self.canvas.delete("all") if __name__ == '__main__': app = MainFrame() app.pack() app.mainloop()