# -*- coding:utf-8 -*- import tkinter import tkinter.filedialog class Scribble2: # ボタンが押された def on_pressed(self, event): # 追加 self.current_line = [(self.color.get(), self.width.get()), (event.x, event.y)] self.data.append(self.current_line) # 追加ここまで self.sx = event.x; self.sy = event.y self.canvas.create_oval(self.sx, self.sy, event.x, event.y, outline = self.color.get(), width = self.width.get()) # ドラッグ def on_dragged(self, event): # 追加 self.current_line.append( (event.x, event.y) ) # 追加ここまで self.canvas.create_line(self.sx, self.sy, event.x, event.y, fill = self.color.get(), width = self.width.get()) self.sx = event.x; self.sy = event.y # ファイルに保存する def on_save(self): filename = tkinter.filedialog.asksaveasfilename(title = "保存", filetypes = [('scribbleファイル', '.data')], initialdir = self.path_name) if filename == "": return fp = open(filename, "w") for path in self.data: fp.write(path[0][0] + ';' + str(path[0][1])) for dot in path[1:]: fp.write(';' + str(dot[0]) + ' ' + str(dot[1])) fp.write('\n') fp.close() ##################################### # ファイルの読み込み # @return 線のデータ def parse_line(self, line): if not isinstance(line, str): raise ValueError("list must be a str") d = line.split(';') cur = [ (d[0], int(d[1])) ] # (color, width) for dot in d[2:]: x, y = dot.split(' ') cur.append( (int(x), int(y)) ) return cur # 線 (または点) を引く def draw_line(self, color, width, dots): # 空のときは何も描かない if len(dots) == 0: return elif len(dots) == 1: x = dots[0][0]; y = dots[0][1] self.canvas.create_oval(x, y, x, y, outline = color, width = width) return # 2以上のとき => 線 sx = None; sy = None for dot in dots: x = dot[0]; y = dot[1] if sx: self.canvas.create_line(sx, sy, x, y, fill = color, width = width ) sx = x; sy = y def on_load(self): filename = tkinter.filedialog.askopenfilename(title = "開く", filetypes = [('scribbleファイル', '.data')], initialdir = self.path_name) if filename == "": return try: fp = open(filename, "r") except IOError as e: print(e) return self.data = [] self.canvas.delete("all") for line in fp: cur = self.parse_line(line) self.data.append(cur) color = cur[0][0]; width = cur[0][1] self.draw_line(color, width, cur[1:]) fp.close() # ファイルの読み込みここまで ##################################### # ウィンドウを作る def create_window(self): window = tkinter.Tk() # メニュー m0 = tkinter.Menu(window) window.configure(menu = m0) # under は [Alt] + ? を表す label 上の位置 m0.add_command(label = '開く(O)...', under = 3, command = self.on_load) m0.add_command(label = '保存(S)...', under = 3, command = self.on_save) m0.add_command(label = '終了(X)', under = 3, command = window.quit) self.canvas = tkinter.Canvas(window, bg = "white", width = 300, height = 300) self.canvas.pack() self.canvas.bind("", self.on_pressed) self.canvas.bind("", self.on_dragged) # 色を選ぶ COLORS = ["red", "green", "blue", "#FF00FF", "black"] self.color = tkinter.StringVar() self.color.set(COLORS[1]) b = tkinter.OptionMenu(window, self.color, *COLORS) b.pack(side = tkinter.LEFT) # 線の太さを選ぶ self.width = tkinter.Scale(window, from_ = 1, to = 15, orient = tkinter.HORIZONTAL) self.width.set(5) self.width.pack(side = tkinter.LEFT) return window; def __init__(self): self.window = self.create_window(); # 呼び出すときはself. + メソッド名 self.data = [] self.path_name = "" def run(self): self.window.mainloop() # 開始 Scribble2().run()