Canvas.create_image(),可拖动的图像似乎没有从它的位置移动?
Canvas.create_image(), draggable image seems not to be moving from its place?
我目前正在使用 Tkinter,我正在尝试制作一个可拖动的 canvas 图像,我从 “制作”/编辑的代码,第二个要特别。当我使用 tk.Frame()
时,这些代码对我有用,但它给出了 Canvas.create_image()
的错误。所以我对它进行了一些编辑,但现在当我拖动它时它似乎在移动图像
我的代码:
from tkinter import *
import pyautogui
x,y=pyautogui.size()
tk = Tk()
c = Canvas(tk, width=x, height=y)
c.place(x=-2,y=-3)
img = ImageTk.PhotoImage(PIL.Image.open(r"Data\backgrounds\background.jpg"))
c.create_image(0, 0, image=img, anchor=NW)
def command6():
print("command6")
def make_draggable(widget,btn="<Button-1>",motion="<B1-Motion>"):
def __draggable__(widget):
c.tag_bind(btn,btn,on_drag_start)
c.tag_bind(motion,motion,on_drag_motion)
def on_drag_start(event):
widget = event.widget
widget._drag_start_x = event.x
widget._drag_start_y = event.y
def on_drag_motion(event):
widget = event.widget
x = widget.winfo_x() - widget._drag_start_x + event.x
y = widget.winfo_y() - widget._drag_start_y + event.y
widget.move(widget,x, y)
__draggable__(widget)
APP_6 = r'apps\File.png'
APP_6 = PIL.Image.open(APP_6)
APP_6 = APP_6.resize((48,48),PIL.Image.ANTIALIAS)
APP_6 = ImageTk.PhotoImage(APP_6)
image_6 = ImageTk.PhotoImage(PIL.Image.open(r"apps\File.png"))
image_id_6 = c.create_image(48,48, image=APP_6)
c.move(image_id_6, 1,y-735)
c.tag_bind(image_id_6, '<Button-1>',command6)
make_draggable(image_id_6)
tk.mainloop()
这不会在控制台中产生错误或任何不需要的输出。
make_draggable()
函数内部有几个问题:
.tag_bind()
的第一个参数是 canvas 项目的 项目 ID。对于您的情况,它是 make_draggable()
的 widget
参数。所以下面几行:
c.tag_bind(btn,btn,on_drag_start)
c.tag_bind(motion,motion,on_drag_motion)
应该改为
c.tag_bind(widget, btn, on_drag_start)
c.tag_bind(widget, motion, on_drag_motion)
同样适用于 c.move(...)
inside on_drag_motion()
- logic/calculation 移动 canvas 项目是错误的
下面是修改后的 make_draggable()
函数:
def make_draggable(widget, btn="<Button-1>", motion="<B1-Motion>"):
def __draggable__(widget):
c.tag_bind(widget, btn, on_drag_start)
c.tag_bind(widget, motion, on_drag_motion)
c._item_id = widget # save the item ID for later use
def on_drag_start(event):
widget = event.widget
# get the top-left coordinates of the selected item
x, y, *_ = widget.bbox(widget._item_id)
# save the offset of current mouse position from the top-left coordinates
widget._dx = event.x - x
widget._dy = event.y - y
def on_drag_motion(event):
widget = event.widget
# calculate the top-left coordinates of the item that the item to be moved to
x = event.x - widget._dx
y = event.y - widget._dy
# move the item using moveto() instead of move()
widget.moveto(widget._item_id, x, y)
__draggable__(widget)
由于以上逻辑只适用于make_draggable()
最后一次调用的item。最好使用 class 而不是 function:
class make_draggable():
def __init__(self, item_id, btn="<Button-1>", motion="<B1-Motion>"):
self.item_id = item_id
c.tag_bind(item_id, btn, self.on_drag_start, add=True)
c.tag_bind(item_id, motion, self.on_drag_motion, add=True)
def on_drag_start(self, event):
x, y, *_ = event.widget.bbox(self.item_id)
self.dx, self.dy = event.x-x, event.y-y
def on_drag_motion(self, event):
event.widget.moveto(self.item_id, event.x-self.dx, event.y-self.dy)
我目前正在使用 Tkinter,我正在尝试制作一个可拖动的 canvas 图像,我从 tk.Frame()
时,这些代码对我有用,但它给出了 Canvas.create_image()
的错误。所以我对它进行了一些编辑,但现在当我拖动它时它似乎在移动图像
我的代码:
from tkinter import *
import pyautogui
x,y=pyautogui.size()
tk = Tk()
c = Canvas(tk, width=x, height=y)
c.place(x=-2,y=-3)
img = ImageTk.PhotoImage(PIL.Image.open(r"Data\backgrounds\background.jpg"))
c.create_image(0, 0, image=img, anchor=NW)
def command6():
print("command6")
def make_draggable(widget,btn="<Button-1>",motion="<B1-Motion>"):
def __draggable__(widget):
c.tag_bind(btn,btn,on_drag_start)
c.tag_bind(motion,motion,on_drag_motion)
def on_drag_start(event):
widget = event.widget
widget._drag_start_x = event.x
widget._drag_start_y = event.y
def on_drag_motion(event):
widget = event.widget
x = widget.winfo_x() - widget._drag_start_x + event.x
y = widget.winfo_y() - widget._drag_start_y + event.y
widget.move(widget,x, y)
__draggable__(widget)
APP_6 = r'apps\File.png'
APP_6 = PIL.Image.open(APP_6)
APP_6 = APP_6.resize((48,48),PIL.Image.ANTIALIAS)
APP_6 = ImageTk.PhotoImage(APP_6)
image_6 = ImageTk.PhotoImage(PIL.Image.open(r"apps\File.png"))
image_id_6 = c.create_image(48,48, image=APP_6)
c.move(image_id_6, 1,y-735)
c.tag_bind(image_id_6, '<Button-1>',command6)
make_draggable(image_id_6)
tk.mainloop()
这不会在控制台中产生错误或任何不需要的输出。
make_draggable()
函数内部有几个问题:
.tag_bind()
的第一个参数是 canvas 项目的 项目 ID。对于您的情况,它是make_draggable()
的widget
参数。所以下面几行:
c.tag_bind(btn,btn,on_drag_start)
c.tag_bind(motion,motion,on_drag_motion)
应该改为
c.tag_bind(widget, btn, on_drag_start)
c.tag_bind(widget, motion, on_drag_motion)
同样适用于 c.move(...)
inside on_drag_motion()
- logic/calculation 移动 canvas 项目是错误的
下面是修改后的 make_draggable()
函数:
def make_draggable(widget, btn="<Button-1>", motion="<B1-Motion>"):
def __draggable__(widget):
c.tag_bind(widget, btn, on_drag_start)
c.tag_bind(widget, motion, on_drag_motion)
c._item_id = widget # save the item ID for later use
def on_drag_start(event):
widget = event.widget
# get the top-left coordinates of the selected item
x, y, *_ = widget.bbox(widget._item_id)
# save the offset of current mouse position from the top-left coordinates
widget._dx = event.x - x
widget._dy = event.y - y
def on_drag_motion(event):
widget = event.widget
# calculate the top-left coordinates of the item that the item to be moved to
x = event.x - widget._dx
y = event.y - widget._dy
# move the item using moveto() instead of move()
widget.moveto(widget._item_id, x, y)
__draggable__(widget)
由于以上逻辑只适用于make_draggable()
最后一次调用的item。最好使用 class 而不是 function:
class make_draggable():
def __init__(self, item_id, btn="<Button-1>", motion="<B1-Motion>"):
self.item_id = item_id
c.tag_bind(item_id, btn, self.on_drag_start, add=True)
c.tag_bind(item_id, motion, self.on_drag_motion, add=True)
def on_drag_start(self, event):
x, y, *_ = event.widget.bbox(self.item_id)
self.dx, self.dy = event.x-x, event.y-y
def on_drag_motion(self, event):
event.widget.moveto(self.item_id, event.x-self.dx, event.y-self.dy)