線や円などの図形の描画のページでは、tkinterでCanvas上に図形を描画しましたが、描画後に図形の移動や移動や変形、削除などを行う事ができ、その方法を紹介します。
ちょうどWordやExcelのように図形を選択し、移動や変形、削除、表示する順番の変更(最前面へ移動、最背面へ移動)などを行う操作と似ているので、これをイメージしてください。
実際にtkinterで、どのように図形を編集するのか?を紹介します。
tagとid
図形を編集するために、それぞれの図形を識別する必要があり、識別のためにid もしくは tag を用います。
id は create_line のように create_ から始まるメソッドを実行するたびに、1から始まるシリアル番号が返されます。
tag は図形を識別するために、create_ から始まるメソッドの tag オプションに任意文字列を指定します。
この文字列は重複していてもよく、複数の図形に同じtagの名前を指定すると、WordやExcelでいうところのグループ化のような事ができます。
(サンプル)
import tkinter as tk
root = tk.Tk()
root.geometry("300x200")
# Canvasの作成
canvas = tk.Canvas(root, bg = "white")
# Canvasを配置
canvas.pack(fill = tk.BOTH, expand = True)
# 線の描画
id1 = canvas.create_line(20, 10, 280, 190, fill = "Red", width = 5, tag="line")
# 矩形の描画
id2 = canvas.create_rectangle(100,50,200,150, fill="Yellow",width = 3, tag="rect")
root.mainloop()
(実行結果)
このプログラムを実行すると、id1=1, id2=2 となります。
以降は、このサンプルをベースに説明します。
また、tag もしくは idを tagOrId と表現します。
図形の削除(delete)
図形を削除します。
.delete(tagOrId)
.delete(“all”) とすると、Canvas上のすべての図形を削除します。
.delete(id1, “rect”)のように複数のtagOrIdを指定することもできます。
(例)
# 線の描画
id1 = canvas.create_line(20, 10, 280, 190, fill = "Red", width = 5, tag="line")
# 矩形の描画
id2 = canvas.create_rectangle(100,50,200,150, fill="Yellow",width = 3, tag="rect")
# 線の削除(id指定)
canvas.delete(id1)
# 線の削除(tag指定)
#canvas.delete("line")
→ |
図形の相対移動(move)
現在の位置からのX方向、Y方向の移動量を指定して、図形を移動します。(相対移動)
.move(tagOrId, x, y)
tagOrId | 移動する図形のid もしくは tag |
x | X方向(右方向が正)に移動する量 |
y | Y方向(下方向が正)に移動する量 |
(例)
# 線の描画
id1 = canvas.create_line(20, 10, 280, 190, fill = "Red", width = 5, tag="line")
# 矩形の描画
id2 = canvas.create_rectangle(100,50,200,150, fill="Yellow",width = 3, tag="rect")
# 矩形の移動(相対座標指定指定)
canvas.move(id2, 50, -30)
→ |
図形の拡大縮小(sacle)
点(xOffset, yOffset)を基点とした拡大縮小
.scale(tagOrId, xOffset, yOffset, xScale, yScale)
tagOrId | 拡大縮小する図形のid もしくは tag |
xOffset | 基点となる点のx座標 |
yOffset | 基点となる点のy座標 |
xScale |
X方向(幅方向)の倍率 |
yScale | Y方向(高さ方向)の倍率 |
(例1)矩形の左上の座標を基点として拡大縮小
# 矩形の描画
id = canvas.create_rectangle(100,50,200,150, fill="Yellow",width = 3, tag="rect")
canvas.create_rectangle(100,50,200,150) # 移動前の位置
# (xOffset, yOffset)を基点とした拡大縮小
canvas.scale(id, 100, 50, 1.5, 0.5) # 矩形の左上の座標を基点に拡大縮小
→ |
(例2)矩形の中心を基点として拡大縮小
# 矩形の描画
id = canvas.create_rectangle(100,50,200,150, fill="Yellow",width = 3, tag="rect")
canvas.create_rectangle(100,50,200,150) # 移動前の位置
# (xOffset, yOffset)を基点とした拡大縮小
canvas.scale(id, 150, 100, 1.5, 0.5) # 矩形の中心を基点に拡大縮小
→ |
図形を構成している座標を指定して変形(coords)
図形を作成した時の座標を書き換えます。
引数にtagOrIdのみを指定すると、図形を構成している座標を[x0, y0, x1, y1, …, xn, yn]のリストで取得します。
.coords(tagOrId, x0, y0, x1, y1, ..., xn, yn)
(例1)図形を構成している座標を指定して変形
# 線の描画
id = canvas.create_line(20, 10, 150, 190, 280, 50, fill = "Red", width = 5, tag="line")
canvas.create_line(20, 10, 150, 190, 280, 50) # 移動前の位置
# 図形を構成している座標を指定して変形
canvas.coords(id, 20, 50, 150, 120, 280, 100)
→ |
(例2)図形を構成している座標を取得し、部分的に座標を変更する
# 線の描画
id = canvas.create_line(20, 10, 150, 190, 280, 50, fill = "Red", width = 5, tag="line")
canvas.create_line(20, 10, 150, 190, 280, 50) # 移動前の位置
# 図形を構成している座標の取得
points = canvas.coords(id)
print(points) # [20.0, 10.0, 150.0, 190.0, 280.0, 50.0]
# 部分的に座標を修正
points[2:4]=[200, 80]
# 図形の変形
points = canvas.coords(id, points)
→ |
前面へ移動(lift)
図形の重なり具合を調整します。
tagOrIdで指定した図形をaboveThisの上へ移動します。
.lift(tagOrId, aboveThis)
tagOrId | 重なりを調整する図形のid もしくは tag |
aboveThis | 移動先の図形のid もしくは tag 指定しない場合、最前面へ移動します。 |
(例)
# 矩形の描画
id1 = canvas.create_rectangle(20,20,120,120, fill="Red",width = 3)
# 線の描画
id2 = canvas.create_line(5,95,220,95, fill="Green",width = 10)
# 矩形の描画
id3 = canvas.create_rectangle(70,70,170,170, fill="Blue",width = 3)
# 矩形(id3)を矩形(id1)の上へ移動
canvas.lift(id3, id1)
→ |
背面へ移動(lower)
図形の重なり具合を調整します。
tagOrIdで指定した図形をbelowThisの下へ移動します。
.lower(tagOrId, belowThis)
tagOrId | 重なりを調整する図形のid もしくは tag |
belowThis | 移動先の図形のid もしくは tag 指定しない場合、最背面へ移動します。 |
(例)
# 矩形の描画
id1 = canvas.create_rectangle(20,20,120,120, fill="Red",width = 3)
# 線の描画
id2 = canvas.create_line(5,95,220,95, fill="Green",width = 10)
# 矩形の描画
id3 = canvas.create_rectangle(70,70,170,170, fill="Blue",width = 3)
# 矩形(id3)を最背面移動
canvas.lower(id3)
→ |
参考
https://tkdocs.com/shipman/canvas-methods.html