我所拥有的是我的河内塔益智游戏的正在进行中。我只是在一两天工作,我在这里遇到的问题如下:如何将对象捕捉到屏幕上的特定位置。此刻发生的事情是对象会根据鼠标触摸对象的位置捕捉到特定位置。
import Tkinter as tk
from Tkinter import *
class SampleApp(tk.Tk):
User_Input = input("How many disks?")
global User_Input
'''Illustrate how to drag items on a Tkinter canvas'''
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# create a canvas
self.canvas = tk.Canvas(width=600, height=600)
self.canvas.pack(fill="both", expand=True)
# this data is used to keep track of an
# item being dragged
self._drag_data = {"x": 0, "y": 0, "item": None, "score": 0}
self._disk_data = {"x": 0, "y": 0}
self._pole1_data = {"x": 102, "y": 425}
self._pole2_data = {"x": 0, "y": 0}
self._pole3_data = {"x": 0, "y": 0}
# create a couple movable OBJECTS
self._create_token((100, 550), "black")
self._create_bases((100, 600), "orange")
self._create_poles((145, 585), "blue")
self.scores(0)
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
self.canvas.tag_bind("token", "<ButtonPress-1>", self.OnTokenButtonPress)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.OnTokenButtonRelease)
self.canvas.tag_bind("token", "<B1-Motion>", self.OnTokenMotion)
def scores(self, score):
global setrep
global score_set
if score >= 0:
self.score_set = Label(self.canvas, text = "Moves: " + str(score), width = 20, height = 5, bg = "black", fg = "white").place(relx = 0.76, rely = 0.82)
def _create_poles(self, coord, color):
(x,y) = coord
for i in range(0, 3):
self.canvas.create_rectangle(x-45, y-30, x-45, y-395, outline = color, fill = color)
x += 150
def _create_bases(self, coord, color):
(x,y) = coord
for i in range(0, 3):
self.canvas.create_rectangle(x-45, y-25, x+45, y-45, outline = color, fill = color)
x += 150
def _create_token(self, coord, color):
'''Create a token at the given coordinate in the given color'''
(x,y) = coord
for i in range(0, User_Input):
self.canvas.create_rectangle(x-45+(8*i), y-25, x+45, y-45, outline=color, fill=color, tags="token")
y -= 50
x -= 4.5
def OnTokenButtonPress(self, event):
'''Being drag of an object'''
# record the item and its location
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 OnTokenButtonRelease(self, event):
'''End drag of an object'''
# reset the drag information
self._drag_data["x"] = 0
self._drag_data["y"] = 0
self._drag_data["score"] += 1
self.scores(self._drag_data["score"])
self.canvas.move(self._drag_data["item"], self._pole1_data["x"]-event.x, self._pole1_data["y"]-event.y)
print event.x, event.y
self._drag_data["item"] = None
def OnTokenMotion(self, event):
'''Handle dragging of an object'''
# compute how much this object has moved
delta_x = event.x - self._drag_data["x"]
delta_y = event.y - self._drag_data["y"]
# move the object the appropriate amount
self.canvas.move(self._drag_data["item"], delta_x, delta_y)
# record the new position
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
我建议只使用1或2个磁盘进行测试,否则可能会造成混淆。
你要看的主要部分是 def TokenButtonRelease(self,event),并声明 self.canvas.move(self._drag_data [“item”], self._pole1_data [“x”] - event.x,self._pole1_data [“y”] - event.y)
问题是“-event.x”和“-event.y”,因为我真的希望减去对象的中心点。所以我的主要问题是如何找到这个,以及如何声明我希望这是必须带走的价值。您会注意到对象会捕捉到某个位置,但是如果您在不同的点抓住该对象,它显然会捕捉到稍微不同的点。
答案 0 :(得分:1)
您可以跟踪字典或某个容器中的左上角。然后,您可以将左上角移动到所需的任何位置,然后更新字典。该程序使用tag_bind来告诉鼠标何时进入矩形,作为识别位置的简单演示,当然您也可以使用按钮释放等。
try
import Tkinter as tk ## Python 2.x
except ImportError:
import tkinter as tk ## Python 3.x
from functools import partial
class SampleApp():
'''Illustrate how to drag items on a Tkinter canvas'''
def __init__(self):
self.user_input=0
self.get_input()
self.top=tk.Tk()
self.create_canvas()
self.x=20
self.y=100
self.rectangle_dict={}
for ctr in range(0, self.user_input):
self.create_rectangle(ctr)
self.top.mainloop()
def create_canvas(self):
self.canvas = tk.Canvas(width=600, height=600)
self.canvas.pack(fill="both", expand=True)
def create_rectangle(self, ctr):
colors=["red", "blue", "green", "orange", "yellow"]
rc = self.canvas.create_rectangle(self.x, self.y,.
self.x+25, self.y+50, outline='white',
fill=colors[ctr])
## call the function, "func1", and send the value
## in ctr to it when the mouse enters
## this rectangle, i.e. different memory
## address/rectangle for "rc" for each
## function call
self.canvas.tag_bind(rc, "<Enter>",
partial(self.func1, ctr))
self.rectangle_dict[ctr]=[self.x, self.y]
self.x += 75
self.y += 100
def func1(self, ctr, event):
""" "bind" sends a Tkinter event which must
be caught even though it is not used
"""
print "Enter called for rectangle number", ctr
print "top left corner is %d, %d" % (self.rectangle_dict[ctr][0],
self.rectangle_dict[ctr][1])
def get_input(self):
""" allow for 1 to 5 rectangles to be created
"""
while self.user_input not in range(1, 6):
self.user_input = raw_input("How many disks? ")
if self.user_input.isdigit():
self.user_input=int(self.user_input)
print "%d disks will be created" % (self.user_input)
SA=SampleApp()