基于使用canvas.create_line
绘制的简单直线,例如这条image here,基于直线的起点、中点和终点创建三个点,example here.
我想要能够点击并拖动有点的那部分Line,所以我做了以下MRE:
import tkinter as tk
root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=400)
canvas.pack()
line = canvas.create_line(50, 50, 350, 50, width=3)
start_x, start_y, end_x, end_y = canvas.coords(line)
start_dot = canvas.create_oval(start_x - 5, start_y - 5, start_x + 5, start_y + 5, fill='blue', tags=('start_dot',))
end_dot = canvas.create_oval(end_x - 5, end_y - 5, end_x + 5, end_y + 5, fill='red', tags=('end_dot',))
mid_x = (start_x + end_x) / 2
mid_y = start_y
mid_dot = canvas.create_oval(mid_x - 5, mid_y - 5, mid_x + 5, mid_y + 5, fill='green', tags=('mid_dot',))
def update_line(event):
global end_x, end_y, start_y, start_x, mid_y, mid_x, curve
x, y = event.x, event.y
item = canvas.find_withtag(tk.CURRENT)[0]
if item == start_dot:
canvas.coords(start_dot, x - 5, y - 5, x + 5, y + 5)
canvas.coords(line, x, y, end_x, end_y)
elif item == end_dot:
canvas.coords(end_dot, x - 5, y - 5, x + 5, y + 5)
canvas.coords(line, start_x, start_y, x, y)
elif item == mid_dot:
dx = x - (start_x + end_x) // 2
dy = y - (start_y + end_y) // 2
canvas.coords(mid_dot, mid_x + dx - 5, mid_y + dy - 5, mid_x + dx + 5, mid_y + dy + 5)
canvas.coords(line, start_x, start_y, mid_x + dx, mid_y + dy, end_x, end_y)
else:
return
test = canvas.coords(line)
if len(test) == 4:
start_x, start_y, end_x, end_y, = canvas.coords(line)
mid_x = (start_x + end_x) / 2
mid_y = (start_y + end_y) / 2
canvas.coords(mid_dot, mid_x - 5, mid_y - 5, mid_x + 5, mid_y + 5)
else:
pass
canvas.tag_bind('start_dot', '<B1-Motion>', update_line)
canvas.tag_bind('end_dot', '<B1-Motion>', update_line)
canvas.tag_bind('mid_dot', '<B1-Motion>', update_line)
root.mainloop()
这在某种程度上是可行的,至少对于仅正确移动开始和结束是这样的.尚不起作用的部分是在移动中点后正确更新直线,然后移动直线的起始点或结束点. Here是显示问题的gif,here是预期行为(可以忽略矩形).
我注意到canvas.coords
个输出5值,而不是我习惯的4个值.
我怎样才能让上面的内容与中间路径/点一起工作呢?
附注:我使用了术语"折线",但我不确定这是否是我在这里真正在做的事情(在查看谷歌图片时,它看起来确实很像).如果有的话,请随意提及一个更合适的术语.