我写了这段代码来练习,它在按下鼠标左键的同时移动了标签:
def motion(self, event):
delta_x = event.x - self._drag_data["x"]
delta_y = event.y - self._drag_data["y"]
self.canvas.move(self._drag_data["item"], delta_x, delta_y)
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
接下来,我尝试将标签移动到已定义的5个像素的网格上。因此,将标签直接“快照”在一起更加容易。
我该怎么做?有没有办法仅每5个像素移动一次标签?因此,每5个像素,标签就会再次跳到光标下方。
以下是我提取函数的示例:
import tkinter as tk
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.canvas = tk.Canvas(width=400, height=400)
self.canvas.pack(fill="both", expand=True)
self._drag_data = {"x": 0, "y": 0, "item": None}
self._create_token((100, 100), "white")
self.canvas.tag_bind("token", "<ButtonPress-1>", self.on_token_press)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.on_token_release)
self.canvas.tag_bind("token", "<B1-Motion>", self.on_token_motion)
def _create_token(self, coord, color):
(x,y) = coord
self.canvas.create_oval(x-25, y-25, x+25, y+25, outline=color, fill=color, tags="token")
def on_token_press(self, event):
self._drag_data["item"] = self.canvas.find_closest(event.x, event.y)[0]
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
def on_token_release(self, event):
self._drag_data["item"] = None
self._drag_data["x"] = 0
self._drag_data["y"] = 0
def on_token_motion(self, event):
delta_x = event.x - self._drag_data["x"]
delta_y = event.y - self._drag_data["y"]
self.canvas.move(self._drag_data["item"], delta_x, delta_y)
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
答案 0 :(得分:2)
在这里,我们将x和y的增量设置为5,然后检查鼠标位置是否在项目的后面/下方,如果是x或y乘以-1,则增量为负值,因此我们的项目将向我们的鼠标。
def motion(self, event):
delta_x = 0
delta_y = 0
step = 5
if abs(event.x - self._drag_data["x"]) >= step:
delta_x = step
if abs(event.y - self._drag_data["y"]) >= step:
delta_y = step
if event.x < self._drag_data["x"]:
delta_x *= -1
if event.y < self._drag_data["y"]:
delta_y *= -1
self.canvas.move(self._drag_data["item"], delta_x, delta_y)
if delta_x != 0:
self._drag_data["x"] = event.x
if delta_y != 0:
self._drag_data["y"] = event.y
答案 1 :(得分:0)
您可以简单地将delta_x
和delta_y
舍入为步长的最接近倍数:
def on_token_motion(self, event):
step = 20
# Calculate drag distance
delta_x = event.x - self._drag_data["x"]
delta_y = event.y - self._drag_data["y"]
# Round to nearest multiple of step size
delta_x = int(step * round(float(delta_x)/step))
delta_y = int(step * round(float(delta_y)/step))
# Move the object
self.canvas.move(self._drag_data["item"], delta_x, delta_y)
# Update _drag_data to the new position
self._drag_data["x"] = self._drag_data["x"] + delta_x
self._drag_data["y"] = self._drag_data["y"] + delta_y
请注意,我还更改了_drag_data
更新。对象的新位置不再等于event.x
,因为我们捕捉到了网格。因此,我们必须将其更新为self._drag_data["x"] + delta_x
,这是旧头寸加上移动的金额。