このページではキャンバスウィジェットで描画した図形を「操作する方法」について解説します。
キャンバスウィジェットの作成方法や図形の描画については下記ページで解説していますので、特にキャンバスの基礎を知りたい方はまずこちらを読んでいただくと良いと思います。
Contents
キャンバス
キャンバスは主に図形を描画するためのウィジェットになります。

tkinter ではキャンバスに対して下記のような図形を描画することができます。
- 長方形
- 多角形
- 楕円
- 円弧
- 線
- テキスト
- ビットマップ
- 画像
キャンバスの基本的な使い方
tkinter におけるキャンバスの基本的な使い方の流れは下記になります。
- メインウィンドウを作成する
- メインウィンドウにキャンバスを作成・配置する
- キャンバスに図形を描画する
- 描画した図形を操作する
特にキャンバスに深く関わるのが 2. 3. 4. の部分です。
下記がこの一連の使い方の流れを踏襲したスクリプト例になります。
# -*- coding:utf-8 -*-
import tkinter
def button_click():
global canvas
# 4. 描画した図形を操作する
color = canvas.itemcget(
"rectangle",
"fill"
)
if color == "blue":
canvas.itemconfig(
"rectangle",
fill="green"
)
else:
canvas.itemconfig(
"rectangle",
fill="blue"
)
# 1. メインウィンドウを作成する
app = tkinter.Tk()
# 2. メインウィンドウにキャンバスを作成・配置する
canvas = tkinter.Canvas(
app,
width=400,
height=300,
)
canvas.pack()
# 3. キャンバスに図形を描画する
canvas.create_rectangle(
50, 50, 300, 250,
fill="blue",
tag="rectangle"
)
# ボタンの作成と配置
button = tkinter.Button(
app,
text="ボタン",
command=button_click
)
button.pack()
# メインループ
app.mainloop()
このページでは特に「4. 描画した図形を操作する」についての解説になります。
「2. メインウィンドウにキャンバスを作成・配置する」に関しては下記ページで、
「3. キャンバスに図形を描画する」に関しては下記ページで別途詳細を解説していますので、こちらについて知りたい方は是非リンクから目的のページに移動していただければと思います。
Canvas クラスでは描画した図形を操作するためのメソッドがたくさん用意されています。
これらのメソッドについてここから解説していきます。
スポンサーリンク
図形 ID とタグ
図形を操作する際には、図形の「図形 ID」および「タグ」が重要になります。
Canvas クラスにより描画した図形は ID およびタグにより管理されます。
描画した図形を後から操作(色を変更したり削除したり)するためには、これらの ID もしくはタグを指定することで、特定の図形に対する操作を行うことができます。
以降では図形を操作するためのメソッドの紹介をしていきますが、メソッドの引数にとなる tagOrId は、このタグと ID のどちらかを指定することを示しています。
図形 ID
ID は図形描画時に自動的に図形に割り振られる数値になります。
create_rectangle 等の create_図形の種類 メソッドの戻り値がこの図形の ID となります。
各図形に対して異なる ID が割り振られますので、同じ ID の図形は同じキャンパス内に存在することはありません。
ID は図形描画時に割り振られ、後から変更することはできません。
タグ
タグは図形に付ける目印みたいなものです。
タグの実体は文字列で、各図形に好きなタグを付けておくことで、後から特定の図形に対して操作することができるようになります。
ただしタグは図形描画時に自動的に割り振られるものではなく、プログラマーが付けたいタグを図形描画時に意図的に設定してやる必要があります。
例えば描画する長方形にタグ "rect_1" を付ける場合は下記のようにして create_rectangle メソッドに tag 属性を指定してやる必要があります。
anvas.create_rectangle(
50, 50, 300, 250,
fill="blue",
tag="rect_1"
)
タグはキャンバス内の複数の図形に対して同じものを付けることができます、
また各図形に対して複数のタグを付けることも可能です。
さらにタグは後から付けたり変更することも可能です。
図形を描画する
Canvas クラスには「図形を描画する」メソッド(create_図形の種類)が用意されています。
図形を描画するメソッドについては下記ページで詳細を解説していますので、図形の描画について詳しく知りたい方はこちらを参考にしてください。
図形を操作する
では図形を操作する方法について解説していきたいと思います。
図形を操作するメソッドは下記になります。
スポンサーリンク
delete
delete は「args で指定した図形をキャンバスから削除するメソッド」です。

delete メソッドの定義は下記になります。
delete(self, *args)
*args にはタグもしくは図形 ID を指定します。複数を指定することも可能です。
例えば "rect_1" と "oval_1"というタグが付けられた図形をキャンバスから削除する場合は、下記のように delete メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.delete("rect_1", "oval_1")
move
move は「tagOrId で指定した図形を、横方向に xAmount ピクセル、縦方向に yAmount ピクセル分移動させるメソッド」です。

move メソッドの定義は下記になります。
move(self, tagOrId, xAmount, yAmount)
xAmount が正の値の場合は左方向、負の値の場合は右方向に移動します。
また yAmount が正の値の場合は下方向、負の値の場合は上方向に移動します。
例えばタグが "rect_1" の図形を右方向に 10 ピクセル、下方向に 50 ピクセル移動させる場合は下記のように move メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.move("rect_1", 10, 50)
moveto
move メソッド同様、moveto メソッドも「図形を移動させるメソッド」です。
move メソッドでは “移動させる量” を指定して図形の移動をさせますが、moveto メソッドでは “移動させる位置” を指定して図形の移動をさせます。

moveto メソッドの定義は下記になります。
moveto(self, tagOrId, x, y)
例えばタグが "rect_1" の図形を座標 (50, 100) に移動させる場合は下記のように moveto メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.moveto("rect_1", 10, 50)
座標 (x, y) に移動するのは、図形の基準になる位置になります。
例えば長方形であれば長方形の左上が座標 (x, y) に移動します。テキストであれば中心が座標 (x, y) に移動します。
こんな感じで図形の種類によってどの位置が基準になるかが異なるので注意してください。
スポンサーリンク
coords
coods メソッドでは move や moveto メソッドと異なり、「図形を移動させるだけでなく図形のサイズも変更する」メソッドです。

coords メソッドの定義は下記になります。
coords(self, tagOrId, x0, y0, x1, y1, ..., xn, yn)
Canvas クラスでは、create_xxx メソッド実行時に指定する座標により、図形を描画する位置とサイズを設定することができます。
coods はその図形描画時に指定する座標を再指定するメソッドです。
図形描画時に指定する座標の数は図形の種類によって異なるので、coords メソッドも指定する座標の数は図形の種類によって異なります。
例えば create_rectangle メソッドを使用して長方形を描画する場合は、長方形の左上の x 座標と y 座標、右下の x 座標と y 座標の4つの座標を指定しますので、coords メソッドで指定する座標の数も4つになります。
例えばタグが "rect_1" の長方形の左上座標を (50, 100)、右下座標を (300, 400) に設定する場合は下記のように coords メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.coords("rect_1", 50, 100, 300, 400)
coords メソッドで座標を指定せず、タグのみを指定した場合は、そのタグの図形の座標情報を取得することができます。
lower
lower メソッドは「図形を背面に移動させるメソッド」です。

lower メソッドの定義は下記になります。
lower(self, tagOrId, belowThis)
描画した図形は縦や横方向の並びではなく、”奥行き” という情報も持っています。つまり、どの図形が前面に表示され、どの図形が背面に表示されるかがこの “奥行き” 情報により決まります。
基本的に、図形は後から描画した図形が前面に描画されることになります。
図形が重なって描画された場合、前面にある図形が表示されることになります。
この図形の並びを変更するときに lower メソッドを使用します。
belowThis を省略して lower メソッドを実行すると、おそらく tagOrId で指定した図形が最背面に移動することになると思います。
belowThis でタグを指定すれば、tagOrId で指定した図形は belowThis で指定した図形よりも1つだけ背面に移動することになります。
例えばタグ "rect_1" の図形をタグ "oval_1" の図形のすぐ背面に移動させる場合は下記のように lower メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.lower("rect_1", "oval_1")
lift
lower メソッドが図形を “背面” に移動させるメソッドであるのに対し、lift メソッドは「図形を “前面” に移動させるメソッド」です。

lift メソッドの定義は下記になります。
lift(self, tagOrId, aboveThis)
aboveThis を省略して lift メソッドを実行すると、おそらく tagOrId で指定した図形が最前面に移動することになると思います。
aboveThis でタグを指定すれば、tagOrId で指定した図形は belowThis で指定した図形よりも1つだけ前面に移動することになります。
例えばタグ "rect_1" の図形をタグ "oval_1" の図形のすぐ前面に移動させる場合は下記のように lift メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.lift("rect_1", "oval_1")
スポンサーリンク
scale
scale メソッドは「図形をリサイズするメソッド」です。

scale メソッドの定義は下記になります。
scale(self, tagOrId, xOffset, yOffset, xScale, yScale)
xScale が横方向への拡大率、yScale が縦方向への拡大率になります。
拡大率に 1.0 よりも小さい数を指定すれば tagOrId で指定した図形のサイズが小さくなり、拡大率に 1.0 よりも大きい数字を指定すれば tagOrId で指定した図形のサイズが大きくなります。
このリサイズは座標 (xOffset yOffset) を基準点として行われます。
例えば図形の中心座標を xOffset と yOffset に指定すれば図形の中心からリサイズが行われますし、図形の左上座標を xOffset と yOffset に指定すれば図形の左上からリサイズが行われます。
図形から離れた位置を xOffset と yOffset に指定した場合、(xOffset, yOffset)から図形の間の空白部分もリサイズされるので図形の位置が変わってしまうので注意が必要です。
例えば左上座標が (50, 50)、右上座標が (100, 100) の長方形 "rect_1" を中心から縦方向に 2 倍、横方向に 3 倍にリサイズする場合は下記のように scale メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.scale("rect_1", 75, 75, 2, 3)
scan_mark・scan_dragto
すみません、このメソッドについての詳細は私も把握できていません…。
ですが、下記のようにメソッドを実行すれば、図形をドラッグ&ドロップすることができるようになるようです。
# -*- coding:utf-8 -*-
import tkinter
press_flag = False
def click(event):
global canvas
global press_flag
press_flag = True
canvas.scan_mark(event.x, event.y)
def motion(event):
global canvas
global press_flag
if press_flag:
canvas.scan_dragto(event.x, event.y, gain=1)
def release(event):
global canvas
global press_flag
if press_flag:
canvas.scan_dragto(event.x, event.y, gain=1)
press_flag = False
app = tkinter.Tk()
canvas = tkinter.Canvas(
app,
width=600,
height=300,
background="white"
)
canvas.pack()
canvas.create_rectangle(
50, 50,
100, 100,
fill="orange",
tag="rect_1"
)
canvas.tag_bind("rect_1", "<ButtonPress>", click)
canvas.tag_bind("rect_1", "<Motion>", motion)
canvas.tag_bind("rect_1", "<ButtonRelease>", release)
app.mainloop()
itemconfig
itemconfig は tagOrId で指定した「図形の設定を変更するメソッド」です。

図形を描画するときに使用する create_xxx メソッド実行時には、キーワード指定で設定を指定することで、図形の様々な設定を変更可能です。
例えば長方形を描画する create_rectangle メソッドでは、実行時に下記のような設定を引数で指定することができます(これはほんの一例です)。
fill:塗りつぶす色outline:線の色with:線の太さ
itemconfig メソッドでは、これらの設定を描画した後から変更することができます。
設定できる項目は図形の種類によって異なりますが、どの図形においても create_xxx メソッド実行時に設定できる項目と同じ項目を itemconfig メソッドで変更することが可能です。
具体的にどのような項目が設定可能であるかは下記ページで解説していますので、詳しく知りたい方はこちらを参考にしてください。
itemconfig メソッドの定義は下記になります。
itemconfig(self, tagOrId, **kw)
一度に複数の設定を変更することも可能です。
例えばタグ "rect_1" の図形の塗り潰し色を “blue”、線の太さを “10” px、線の色を “red” に設定する場合は下記のように itemconfig メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.itemconfig("rect_1", fill="blue", width=10, outline="red")
ポイントはキーワード指定で設定を指定するところです。
スポンサーリンク
図形の情報を取得する
次は図形の情報を取得するメソッドについて解説していきます。
図形の情報を取得するメソッドは下記の3つになります。
itemcget
itemconfig が tagOrId で指定した図形の設定を変更するメソッドであるのに対し、この itemcget は「図形の設定を取得するメソッド」です。

取得できる設定の項目は itemconfig と同様です。
itemcget メソッドの定義は下記になります。
itemcget(self, tagOrId, option)
option には取得したい設定の項目名を文字列形式で指定します。
返却値は option で指定した項目名に対する設定値になります。
例えばタグ "rect_1" の図形の塗り潰し色を取得する場合は下記のように itemcget メソッドを実行します。
# canvas は Canvas クラスのインスタンス
value = canvas.itemcget("rect_1", "fill")
print(value)
itemcget では1度に取得できる設定は1つのみになります。
type
type は tagOrId で指定した「図形の種類を取得するメソッド」です。

type メソッドの定義は下記になります。
type(self, tagOrId)
返却値は図形の種類を表す文字列になります。
例えば長方形の場合は "rectangle"、楕円の場合は "oval" が返却されます。
例えばタグ "rect_1" の図形の種類を取得する場合は下記のように type メソッドを実行します。
# canvas は Canvas クラスのインスタンス
type = canvas.type("rect_1")
print(type)
スポンサーリンク
bbox
bbox は tagOrId で指定した「図形が存在する位置を取得するメソッド」です。

bbox メソッドの定義は下記になります。
bbox(self, tagOrId)
返却値は矩形を表す4つの数字のタプル (x0, y0, x1, y1)になります。
(x0, y0)は矩形の左上、(x1, y1)は矩形の右下の座標をそれぞれ表しており、tagOrId で指定した図形がその矩形の中に存在することを意味しています。
例えばタグ "rect_1" の図形の位置を取得する場合は下記のように bbox メソッドを実行します。
# canvas は Canvas クラスのインスタンス
pos = canvas.bbox("rect_1")
print(post)
図形にイベントを設定する
tkiter の Canvas クラスにより描画した図形は、図形単位でイベントの設定を行うことができます。
イベントについてまず知りたい方は、下記ページで詳しく解説していますので是非こちらのページを読んでみてください!
図形に対してイベントを設定するメソッドは下記の2つになります。
tag_bind
tag_bind は tagOrId で指定した「図形にイベント処理を設定するメソッド」です。

tag_bind メソッドの定義は下記になります。
tag_bind(self, tagOrId, sequence, func, add)
add は省略可能です。
tag_bind メソッドを実行することで sequence で指定したイベント発生時に func で指定したイベントハンドラが自動的に実行されるようになります。
例えば描画した図形がマウスでクリックされた場合に特定の処理を制御するようなこともできます。
どのイベントが発生したときにイベント処理を行うかを指定するのが sequence で、そのイベントが発生したときにどんな処理を行わせるかを指定するのが func になります(func は関数名を指定)。
sequence にどのようなものを設定できるかは下記ページを参考にしてください。
例えばタグ "rect_1" がマウスでクリックされた場合に図形の色を青色に変更するしたい場合は、下記のように関数(change_color)を用意し、tag_bind メソッドを実行します。
# -*- coding:utf-8 -*-
import tkinter
def change_color(event):
event.widget.itemconfig(
"rect_1",
fill="blue"
)
app = tkinter.Tk()
canvas = tkinter.Canvas(
app,
width=400,
height=300,
)
canvas.pack()
canvas.create_rectangle(
50, 50, 300, 250,
fill="red",
tag="rect_1"
)
canvas.tag_bind(
"rect_1",
"<ButtonPress>",
change_color
)
# メインループ
app.mainloop()
スポンサーリンク
tag_unbind
tag_unbind は tag_bindメソッドで設定した「イベント処理を取り消すメソッド」です。
tag_unbind(self, tagOrId, sequence, func_id)
func_id は省略可能です。
tag_unbind メソッドを実行することで tagOrId で指定した図形に対する sequence に設定されたイベント処理を取り消すことができます。
同一の tagOrId、sequence に複数のイベントハンドラを設定している場合、特定のイベントハンドラに対するイベント処理のみを取り消すことができます。この場合は func_id を指定します。
func_id は整数を指定します。例えば最初に tag_bind で設定したイベントハンドラに対するイベント処理を取り消す場合は 0 を指定します。
例えばタグ "rect_1" がマウスでクリックされた場合のイベント処理設定を取り消したい場合は、下記のように tag_unbind メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.tag_unbind(
"rect_1",
"<ButtonPress>"
)
図形にタグを付ける
タグは図形描画時だけでなく、描画した後から付けることも可能です。
下記は Canvas クラスに用意された、描画した後の図形にタグを付けるためのメソッドです。
- addtag_all
- addtag_above
- addtag_below
- addtag_closest
- addtag_enclosed
- addtag_overlapping
- addtag_withtag
addtag_all
addtag_all は、このメソッドを実行したキャンバス内に存在する「全ての図形に対して newtag で指定したタグを一括で付けるメソッド」です。

addtag_all メソッドの定義は下記になります。
addtag_all(self, newtag)
例えば下の図のように長方形・楕円・線が描画されていれば、これら全ての図形に対して newtag で指定したタグが付けられます。
addtag_all の使用例は下記のようになります。
# canvas は Canvas クラスのインスタンス
canvas.addtag_all()
スポンサーリンク
addtag_above
前述の lower メソッドでも解説した通り、描画した図形は “奥行き” 情報によりどの図形が前面に、どの図形が背面に表示されるかが管理されています。
addtag_above は、tagOrId で指定した図形の 「“1つだけ前面” に存在する図形にタグ newtag を付けるメソッド」になります。

addtag_above メソッドの定義は下記になります。
addtag_above(self, newtag, tagOrId)
"rect_1" というタグが付けられた図形の1つ前面に存在する図形に対して "rect_1_above" というタグを付ける場合は下記のように addtag_above メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.addtag_above("rect_1_above", "rect_1")
addtag_below
addtag_above が tagOrId で指定した図形の “1つだけ前面” に存在する図形にタグ newtag を付けるメソッドであるのに対し、addtag_below は tagOrId で指定した図形の「“1つだけ背面” に存在する図形にタグ newtag を付けるメソッド」になります。

addtag_below メソッドの定義は下記になります。
addtag_below(self, newtag, tagOrId)
"rect_1" というタグが付けられた図形の “1つだけ背面” に存在する図形に対して "rect_1_below" というタグを付ける場合は下記のように addtag_below メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.addtag_below("rect_1_below", "rect_1")
addtag_closest
addtag_closest は「指定した座標に一番近い図形にタグを付けるメソッド」です。

addtag_closest メソッドの定義は下記になります。
addtag_closest(self, newtag, x, y, halo=None, start=None)
halo と start は省略可能です(というか私は使い方わかってないです…)。
例えば座標 (100, 100) に一番近くにある図形に "rect_closest" というタグを付ける場合は下記のように addtag_closest メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.addtag_closest("rect_closest", 100, 100)
スポンサーリンク
addtag_enclosed
addtag_enclosed は引数で「矩形内に存在する図形にタグを付けるメソッド」です。
引数で指定した矩形内に「完全に収まっている図形」にのみタグが付けられます。

addtag_enclosed メソッドの定義は下記になります。
addtag_enclosed(self, newtag, x1, y1, x2, y2)
矩形 (100, 50) – (300, 100) 内に完全に収まる図形に "obj_rec" と言うタグを付けるときの addtag_enclosed メソッドの使用例は下記のようになります。
# canvas は Canvas クラスのインスタンス
canvas.addtag_enclosed("obj_rec", 100, 50, 300, 100)
addtag_overlapping
addtag_overlapping は「指定した矩形内に存在する図形にタグを付けるメソッド」です。
addtag_enclosed とは異なり、引数で指定した矩形内に「一部でも収まっている図形」全てにタグが付けられます。

addtag_overlapping メソッドの定義は下記になります。
addtag_overlapping(self, newtag, x1, y1, x2, y2)
矩形 (100, 50) – (300, 100) 内に一部でも収まっている図形に "obj_rec" と言うタグを付けるときの addtag_overlapping メソッドの使用例は下記のようになります。
# canvas は Canvas クラスのインスタンス
canvas.addtag_overlapping("obj_rec",100, 50, 300, 100)
addtag_withtag
addtag_withtag は「tagOrId で直接図形を指定し、その図形にタグを付けるメソッド」です。

tagOrId にタグ名を指定した場合、同じタグを持つ全ての図形に一括でタグが付けられます。
addtag_withtag メソッドの定義は下記になります。
addtag_withtag(self, newtag, tagOrId)
例えば "rect_1" というタグが付けられた図形に、新たに "new_rect" というタグを付ける場合、下記のように addtag_withtag メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.addtag_withtag("new_rect", "rect_1")
スポンサーリンク
タグを削除する
図形に付けられたタグを削除することも可能です。
この削除は dtag メソッドにより行うことができます。
dtag
dtag は tagOrId で指定した図形から「タグを削除するメソッド」です。

dtag メソッドの定義は下記になります。
addtag_withtag(self, tagOrId, deleteTag)
deleteTag は削除したいタグ名を指定します。deleteTag を指定した場合は、tagOrId で指定した図形から deleteTag で指定したタグのみが削除されます。
deleteTag を省略した場合は、tagOrId で指定した図形から全てのタグが削除されます。
例えば "rect_1" というタグが付けられた図形から、"new_rect" というタグ削除する場合、下記のように dtag メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.dtag("rect_1", "new_rect")
タグを取得する
図形に付けられたタグを後から取得することもできます。このメソッドとして gettags が用意されています。
スポンサーリンク
gettags は tagOrId で指定された図形に付けられた「タグを取得するメソッド」です。

gettags メソッドの定義は下記になります。
gettags(self, tagOrId)
返却値は tagOrId に付けられたタグが格納されたタプルになります。
例えば図形 ID が 1 の図形のタグを取得する場合、下記のように gettags メソッドを実行します。
# canvas は Canvas クラスのインスタンス
tag_list = canvas.gettags(1)
print(tag_list)
図形の ID を取得する
次は図形の ID を取得するメソッドについて解説していきます。
図形の ID を取得するメソッドは下記の7つになります。
- find_all
- find_above
- find_below
- find_closest
- find_enclosed
- find_overlapping
- find_withtag
ご覧の通り図形にタグを付けるで紹介したメソッドとそれぞれ対になるメソッドばかりです。タグを付けるか、ID を取得するかの違いがあるだけで、どの図形に対して実行するかが異なるだけです。
ですので、ここでは find_all と find_closest についてのみ解説し、他のメソッドについては省略させていただきます。
どの図形に対して ID を取得するかは対になる図形にタグを付けるで紹介したメソッドを参考にしてください。
find_xxx メソッドの返却値はオブジェクト ID が格納されたタプルになります。
find_all
find_all は「キャンバス内の全ての図形の図形 ID を取得するメソッド」です。
find_all メソッドの定義は下記になります。
find_all(self)
返却値はキャンバス内に存在する図形の ID を格納したタプルになります。
キャンバス内に存在する図形の ID を取得する場合、下記のように find_all メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.find_all()
スポンサーリンク
find_closest
find_closest は「指定した座標に一番近い図形の ID を取得するメソッド」です。
find_closest メソッドの定義は下記になります。
find_closest(self, x, y, halo=None, start=None)
halo と start は省略可能です(これについても私は使い方わかってないです…)。
例えば下記のように find_closest メソッドを実行することで、座標 (100, 100) の一番近くにある図形の ID をメソッドの返却値として取得することができます。
# canvas は Canvas クラスのインスタンス
canvas.find_closest(100, 100)
ただし、返却されるオブジェクトはタプル形式になっているので注意してください。
この find_closest はマウスでクリックされた図形などを特定するときに便利なメソッドです。
例えば下記のように find_closest メソッドを利用することで、キャンバス上の複数の図形の中からマウスカーソルの位置に一番近い図形の ID を取得し、その図形のみに対して操作を行うようなことが可能です。
import tkinter
def onMotion(event):
# マウスカーソルの位置に一番近い図形のIDのタプルを取得
closest_ids = canvas.find_closest(event.x, event.y)
# タプルの先頭の要素を取得
closest_id = closest_ids[0]
# 一旦全ての正方形の色を元に戻す
canvas.itemconfig("all", fill="gray")
# マウスカーソルに一番近い図形のみ色を変更する
canvas.itemconfig(closest_id, fill="orange")
NUM_H = 8
NUM_V = 5
app = tkinter.Tk()
canvas = tkinter.Canvas(
app,
width=NUM_H*50,
height=NUM_V*50,
highlightthickness=0
)
canvas.pack()
# 正方形をNUM_H*NUM_V個描画
for h in range(NUM_H):
for v in range(NUM_V):
canvas.create_rectangle(
50 * h, 50 * v,
50 * (h + 1), 50 * (v + 1),
fill="gray"
)
canvas.bind("<Motion>", onMotion)
app.mainloop()
上記スクリプトでは onMotion 関数がマウスカーソル移動時に実行され、その onMotion 関数の中で find_closest(event.x, event.y) を実行することでマウスカーソルの位置に一番近い図形の ID を取得しています。
さらに、その図形 ID に対して itemconfig メソッドを実行することで、その図形の塗りつぶし色の変更を行なっています。このような処理を行うことで、下のアニメのようにマウスカーソルの位置の図形の色のみ変化するという動作を実現しています。

こんな感じで、ここで紹介した find_closest をはじめとする「図形の ID を取得するメソッド」は、複数の図形の中から特定の図形のみに対して操作を行う際に便利なメソッドです。
また、上記スクリプトで使用している bind メソッドや onMotion 関数の引数 event については下記ページで解説していますので、詳しく知りたい方は下記ページを別途参照していただければと思います。
テキストを操作する
Canvas クラスには create_text で描画したテキスト専用のメソッドも用意されています。
正直あまり使わないと思うので、ここでは簡単に紹介していきたいと思います(正直私もこれらが出来て何が嬉しいのかよくわかっていないです…)。
テキストを操作するメソッドは下記になります。
dchars
dchars は「テキスト図形の文字を削除するメソッド」です。

dchars メソッドの定義は下記になります。
dchars(self, tagOrId, start, last)
start から last により何文字目から何文字目までを削除するかを指定します。文字列の先頭は0文字目になりますのでこの点には注意してください。
"text_1" というタグのテキストの2文字目から5文字目を削除する場合、下記のように dchars メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.dchars("text_1", 2, 5)
スポンサーリンク
icursor・index・insert
icursor はテキスト図形の文字列の特定の位置に文字挿入用カーソルを合わせるメソッド、index はテキスト図形の文字列の特定の位置取得するメソッド、insert はテキスト図形の文字列の特定の位置に文字列を挿入するメソッドです。

それぞれのメソッドの定義は下記になります。
icursor(self, tagOrId, index)
index(self, tagOrId, index)
insert(self, tagOrId, index, text)
"text_1" というタグのテキストの第3文字の前に文字挿入用カーソルを合わせ、その位置から “ABCD” という文字列を挿入する場合、下記のように icursor メソッドと insert メソッドを実行します。
さらに最後に実行する index メソッドにより、現在カーソルが合わせられている位置(先頭から何文字目か)を数値として取得することができます。
# canvas は Canvas クラスのインスタンス
canvas.icursor("text_1", 3)
canvas.insert("text_1", tkinter.INSERT, "ABCD")
num = canvas.index("text_1", tkinter.INSERT)
tkinter.INSERT は「現在のカーソル位置」を表す識別子になります。
なので、1行目で先頭から第3文字の前にカーソルが合わせられ、2行目でそのカーソル位置に "ABCD" を挿入し、この挿入によりカーソルがその挿入した "ABCD" の後ろの位置に移動するため、3行目で取得できる num は 7 となります。
select_from・select_to
select_from と select_to は、テキスト図形の文字列を選択するメソッドです。

それぞれのメソッドの定義は下記になります。
select_from(self, tagOrId, index)
select_to(self, tagOrId, index)
select_from メソッドの index で指定した位置の文字からselect_to メソッドの index で指定した位置の文字までが選択されることになります。
"text_1" というタグのテキストの2文字目から5文字目を選択する場合、下記のように select_from メソッドと select_to メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.select_from("text_1", 2)
canvas.select_to("text_1", 5)
選択された範囲の色を変更するためには、Canvas クラスのコンストラクタでselectbackground で色を設定します。
select_item・select_clear
select_item は文字列の選択が現在行われている図形の ID を取得するメソッド、 select_clear は選択を解除するメソッドです。
それぞれのメソッドの定義は下記になります。
select_item(self)
select_clear(self)
現在文字列が選択されている図形の ID を取得する場合、下記のように select_item メソッドを実行します。
# canvas は Canvas クラスのインスタンス
id = canvas.select_item()
print(id)
スポンサーリンク
その他
ここまでがこのページのメインとなる図形に対するメソッドの紹介になります。ここではその他のメソッドを紹介していきます。
postscript
postscript は「キャンバス全体をポストスクリプトと言われるデータ形式で出力するメソッド」です。

postscript メソッドの定義は下記になります。
postscript(self, option, ...)
キャンバス全体を "canvas.ps" という名前のファイルに出力する場合、下記のように postscript メソッドを実行します。
# canvas は Canvas クラスのインスタンス
canvas.postscript(file="canvas.ps")
Mac だと .ps ファイルは「プレビュー」、Windows だと「Adobe Acrobat」等で開くことができます(PDF に変換されて表示される)。
まとめ
このページでは tkinter の Canvas クラスを利用して描画した図形を操作する方法について解説しました。
多くのメソッドを紹介しましたが、特によく使うのは下記あたりかなぁと思います。
deleteitemconfigitemcgetcoordslowerlifttag_bindfind_closest
おそらくこのページを読んでくださった方は気づいていると思いますが、図形を後から操作するためにはタグが非常に重要です。
後から操作する可能性のある図形には図形描画時にタグをしっかり付けておくことをオススメします。
addtag_xxxx メソッドを利用して図形描画後にタグを付けることも可能ですが、図形描画時にタグを付けるのが一番簡単だと思います。
図形の操作ができるようになるとゲームなども作りやすくなります。
是非図形の操作に迷った時はこのページを参考にしてください!
キャンバス関連の記事は下記にも公開していますので、キャンバスの作り方や設定方法、キャンバスへの図形の描画方法について詳しく知りたい方は、是非こちらのページも読んでみてください!

