tkinter canvas.coords()与canvas.moveto()坐标不同
我尝试了以下脚本,在一个填满整个窗口的canvas
上:
import tkinter as tk
from PIL import Image, ImageTk
from time import *
root = tk.Tk()
root.geometry("500x500")
canvas = tk.Canvas(root)
canvas.pack()
def fill(event):
canvas.config(width = root.winfo_width(), height = root.winfo_height())
root.bind("<Configure>", fill)
img = Image.open("CO2.png")
imgtk = ImageTk.PhotoImage(img)
item = canvas.create_image(15, 15, image = imgtk)
while True:
canvas.moveto(item, canvas.coords(item)[0], canvas.coords(item)[1])
root.update()
sleep(0.5)
理论上,这个操作应该没什么效果,因为它只是把一个物体移动到它原本的位置。但实际上,这个操作却把图像向正的x和y方向移动了,这意味着通过canvas.coords()
获取的坐标有点不准确,和canvas.moveto()
的结果不一致。
这是我使用的图像:
这到底是怎么回事呢?
1 个回答
2
这个行为是有说明的,你看到的功能就是这样设计的。
canvas.coords(item)
会返回这个物体现在的位置。
canvas.moveto(item, *coord_list)
会把这个物体放到指定的坐标位置,确保它的左上角在 *coord_list
中给出的坐标的下面和旁边。
如果没有指定坐标,这个命令会返回一个列表,列表里的元素是由 tagOrId 指定的物体的坐标。
还有
在画布坐标空间中移动由 tagOrId 指定的物体,使得第一个物体(在显示列表中最底下的那个)左上角的坐标位于 (xPos,yPos) 这个位置。
这段小代码展示了你的体验:
import tkinter as tk
def test(event):
cnvs.moveto(rect, *cnvs.coords(rect)[0:-2])
root = tk.Tk()
cnvs = tk.Canvas(root, highlightthickness=0)
cnvs.pack()
rect = cnvs.create_rectangle(0,0,50,50, fill='red')
print(cnvs.coords(rect))
root.bind('<1>', test)
root.mainloop()
如果把函数 test 改成下面这样,就能解决问题:
def test(event):
delta = int(float(cnvs.itemcget(rect, 'width'))/2)
coords = [coordinate-delta for coordinate in cnvs.coords(rect)[0:-2]]
cnvs.moveto(rect, *coords)
不过,你还需要根据不同的物体类型和其他坐标属性进行调整。通常情况下,使用 tk 和 tkinter 更新坐标的方法是用 canvas.coords(item, *new_coords)
。