HOME | 8. Menu を使ったシンプル 画像 Viewer | Python | 10. キャンバスにドラッグできるオブジェクトを描こう | download | 書き込む |
この章では、Tk.Canvas について簡単に説明した後、まず手始めにチェス版と碁盤を作ってみます。
Tk.Canvas(master, **options)Tk.Canvas には以下の特徴があります。
.delete(ID) | ID で指定されたオブジェクトを削除します。 |
.itemcget(ID, option) | ID で指定されたオブジェクトの option の値を返します。 |
.itemconfigure(ID, option) | ID で指定されたオブジェクトの属性を指定します。 |
.move(ID, x, y) | ID で指定されたオブジェクトを (x, y) だけ動かします。 |
.scale(ID, x0, y0, rx, ry) | ID で指定されたオブジェクトを、(x0, y0) を基準点にして、 (rx, ry) だけ拡大します。 |
.tag_bind(ID, event, func) | ID で指定されたオブジェクトと event を結びつけ、event が起こると func が呼ばれるようにします。 |
Object | 作成するメソッド | 説明 |
---|---|---|
弧 | .create_arc() | 円弧(の一部)を描きます。PIESLICE, CHORD, ARC の3つのタイプがあります。 see TkRef 6.3. The canvas arc object |
ビットマップ | .create_bitmap() | ビットマップイメージを作成します。 See TkRef 6.4. The canvas bitmap object |
イメージ | .create_image() | Graphic Image を作成します。 See TkRef 6.5. The canvas image object |
線分 | .create_line() | 線分を描きます。曲線も描くことができます。 See TkRef 6.6. The canvas line object |
楕円 | .create_oval() | 円、楕円を描きます。 See TkRef 6.7. The canvas oval object |
多角形 | .create_polygon() | See TkRef 6.8. The canvas polygon object |
長方形 | create_rectangle() | See TkRef 6.8. The canvas rectangle object |
テキスト | .create_text() | See TkRef 6.10. The canvas text object |
ウインドウ | .create_window() | Tk.Canvas 上に他の widget を入れるとき使います。 See TkRef 6.11. The canvas window object |
[code 1] (8queens.py)
01: #! /usr/bin/env python 02: 03: """ 04: eight queens, whose gui uses Tkinter 05: """ 06: 07: import Tkinter as Tk 08: import queen as Q 09: 10: 11: 12: Q_font = ("Times", 14) 13: 14: 15: 16: def move_queen(now, next): 17: return [(i, z1-z0) for i, (z0, z1) in enumerate(zip(now, next)) if z0 != z1] 18: 19: 20: 21: class Cboard(Tk.Canvas): 22: cell_size = 46 23: margin = 5 24: q_images = [] 25: q_figure = [] 26: 27: def __init__(self, master): 28: cwidth = 8*self.cell_size 29: 30: Tk.Canvas.__init__(self, master, relief=Tk.RAISED, bd=4, bg='white', 31: width=cwidth, height=cwidth) 32: 33: self.q_answers = Q.eight_queens() 34: 35: 36: for i in range(8): 37: 38: for j in range(8): 39: bcolor = (i-j)%2==0 and "#699C69" or "#D4D49F" 40: x0 = i*self.cell_size + self.margin 41: y0 = j*self.cell_size + self.margin 42: self.create_rectangle(x0, y0, x0+self.cell_size, y0+self.cell_size, fill=bcolor, width=0) 43: 44: self.q_images.append(Tk.PhotoImage(file="queen.gif")) 45: z = self.q_answers[0][i] 46: x = self.cell_size*((z / 8)+0.5) + self.margin 47: y = self.cell_size*((z % 8)+0.5) + self.margin 48: self.q_figure.append(self.create_image(x, y, image=self.q_images[i], tags="queen")) 49: 50: 51: def refresh(self, now, next): 52: answer_now = self.q_answers[now] 53: answer_next = self.q_answers[now+next] 54: for i, j in move_queen(answer_now, answer_next): 55: self.move(self.q_figure[i], 0, j*self.cell_size) 56: 57: 58: 59: 60: class Queen(Tk.Frame): 61: 62: def __init__(self, master=None): 63: Tk.Frame.__init__(self, master) 64: self.master.title("8 Queens") 65: 66: 67: # title 68: l_title = Tk.Label(self, text='Eight Queens', font=('Times', '24', ('italic', 'bold')), 69: fg='#191970', bg='#EEE8AA', width=12) 70: l_title.pack(padx=10, pady=10) 71: 72: # chess board 73: self.f_board = Cboard(self) 74: self.f_board.pack(padx=10, pady=10) 75: 76: # buttons and a counter 77: self.q_counter = 0 78: self.f_footer = Tk.Frame(self) 79: self.f_footer.pack() 80: self.s_counter = Tk.StringVar() 81: self.s_counter.set("%d/12" % (1 + self.q_counter)) 82: self.a_button = Tk.Button(self.f_footer, text="next", font=Q_font, command = self.show_next) 83: self.a_button.pack(side=Tk.LEFT, padx=5,pady=5) 84: self.b_button = Tk.Button(self.f_footer, text="prev", font=Q_font, command = self.show_prev) 85: self.b_button.pack(side=Tk.LEFT, padx=5,pady=5) 86: self.f_label = Tk.Label(self.f_footer, textvariable = self.s_counter, font=Q_font) 87: self.f_label.pack(side=Tk.LEFT, padx=5, pady=5) 88: 89: 90: def show_next(self): 91: if(self.q_counter < 11): 92: self.f_board.refresh(self.q_counter, 1) 93: self.change_counter(1) 94: 95: 96: def show_prev(self): 97: if(self.q_counter > 0): 98: self.f_board.refresh(self.q_counter, -1) 99: self.change_counter(-1) 100: 101: 102: def change_counter(self, i): 103: self.q_counter += i 104: self.s_counter.set("%d/12" % (1 + self.q_counter)) 105: 106: 107: ##--------------------------------------------------- 108: if __name__ == "__main__": 109: app = Queen() 110: app.pack() 111: app.mainloop()
01: class Gboard(Tk.Canvas): 02: """Tk.Canvas for Go Board""" 03: 04: grid_size = 20 05: stones = dict() 06: 07: 08: def __init__(self, master): 09: 10: en = self.grid_size * 19 11: z = self.grid_size * 0.36 12: hosi = 2 13: 14: Tk.Canvas.__init__(self, master, relief=Tk.RAISED, bd=4, bg="#F7EE8A", 15: width=20*self.grid_size, height=20*self.grid_size, highlightthickness=0) 16: # binding the goban canvas to put_stones method 17: self.bind("<1>", self.put_stones) 18: 19: # drawing lines and coordinate 20: for i in range(19): 21: x= (i+1) * self.grid_size 22: self.create_line(x, self.grid_size, x, en) 23: self.create_line( self.grid_size, x, en, x) 24: 25: self.create_text(z, x, text=str(i), justify=Tk.RIGHT, fill=" #002010", 26: font = ("Helvetica","6","normal")) 27: self.create_text(x, z , text=str(i), justify=Tk.CENTER, fill="#002010", 28: font = ("Helvetica","6","normal")) 29: 30: # drawing black dots 31: for i in range(4,17,6): 32: for j in range(4,17,6): 33: x = i * self.grid_size 34: y = j * self.grid_size 35: self.create_oval(x-hosi, y-hosi, x+hosi, y+hosi, fill= "black") 36: 37: 38: 39: 40: def bclear(self): 41: """ clear stones in the map and on the canvas""" 42: self.stones.clear() 43: self.delete("stone") 44: 45: 46: 47: 48: def bopen (self, fname): 49: """open *.gbn file, whose content is ( [kuro ishi positions], [shiro ishi positions])""" 50: fp = file(fname) 51: lb, lw = eval(rm_cmt(fp.read())) 52: fp.close() 53: 54: for row, col in lb: 55: self.stones[(row,col)] = self.put_a_stone(row, col, "black") 56: 57: for row, col in lw: 58: self.stones[(row,col)] = self.put_a_stone(row, col, "white") 59: 60: 61: 62: 63: def bsave(self, fname): 64: """ save positions of stones in a file """ 65: lb = [] 66: lw = [] 67: for key, val in self.stones.iteritems(): 68: if self.itemcget(val, "fill") == "black": 69: lb.append(key) 70: else: 71: lw.append(key) 72: fp = file(fname, 'w') 73: fp.write("-- ([black stones], [white stones])\n") 74: fp.write ("(\n ") 75: fp.write(str(lb)) 76: fp.write(",\n ") 77: fp.write(str(lw)) 78: fp.write("\n)\n") 79: fp.close() 80: 81: 82: 83: 84: def put_stones(self, event): 85: """ putting go ishis on the goban, 86: this function is bounded to the left one click of the mouse""" 87: 88: cx = self.canvasx(event.x, self.grid_size) 89: cy = self.canvasy(event.y, self.grid_size) 90: 91: col = int(cx/self.grid_size) - 1 92: row = int(cy/self.grid_size) - 1 93: if (0<=row<=18 and 0<=col<=18): 94: if (not ((row,col) in self.stones)) : 95: self.stones[(row,col)] = self.put_a_stone(row, col, "black") 96: elif(self.itemcget(self.stones[(row,col)], "fill") == "black"): 97: self.itemconfig(self.stones[(row,col)], fill="white") 98: else: 99: self.delete(self.stones[(row,col)]) 100: del self.stones[(row,col)] 101: 102: 103: 104: 105: def put_a_stone(self, row, col, color): 106: """ it drows a go-ishi on the goban canvas and returns the go-ishi's ID """ 107: r = self.grid_size * 0.45 108: x_left = (col+1)*self.grid_size-r 109: x_right = (col+1)*self.grid_size+r 110: y_top = (row+1)*self.grid_size-r 111: y_bottom = (row+1)*self.grid_size+r 112: return self.create_oval(x_left, y_top, x_right, y_bottom, fill = color, tags = "stone") 113: 114: 115: 116: 117: def add_n_on_stone(self, i, row, col, tcolor): 118: """ draw number of a stone """ 119: return self.create_text((col+1)*self.grid_size, (row+1)*self.grid_size, 120: text=str(i+1), justify=Tk.CENTER, fill=tcolor, 121: font = ("Helvetica","8","bold"), tags="stone")
次回は大画面の Tk.Canvas を用いて スクロールバーのつけ方について解説します。
HOME | 8. Menu を使ったシンプル 画像 Viewer | Python | 10. キャンバスにドラッグできるオブジェクトを描こう | download | 書き込む |