我正在尝试修改此处发布的示例脚本:
board-drawing code to move an oval
原始脚本允许您单击并拖动画布周围的对象。我改变它,以便按钮移动第一个对象,但我得到一个按钮错误: TypeError:button_move()只需2个参数(给定1个) 我不明白第二个论点应该是什么。
以下是修改过的脚本:
import Tkinter as tk
class Example(tk.Frame):
'''Illustrate how to drag items on a Tkinter canvas'''
def __init__(self, parent):
tk.Frame.__init__(self, parent)
# create a canvas
self.canvas = tk.Canvas(width=400, height=400)
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}
# create a couple of movable objects
self._create_token((100, 100), "white")
self._create_token((200, 100), "black")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
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)
#-----------------------------------------------------------------------------
self.canvas.button2 = tk.Button(self.canvas, text="Button Test",
command=self.button_move)
self.canvas.button2.config(bg="cyan",fg="black")
self.canvas.button2.pack(side='top')
self.canvas.tag_bind("button2", "<ButtonPress-1>", self.button_move)
#-----------------------------------------------------------------------------
def _create_token(self, coord, color):
'''Create a token at the given coordinate in the given 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):
'''Begining 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 on_token_release(self, event):
'''End drag of an object'''
# reset the drag information
self._drag_data["item"] = None
self._drag_data["x"] = 0
self._drag_data["y"] = 0
def on_token_motion(self, event):
'''Handle dragging of an object'''
# compute how much the mouse 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
#-----------------------------------------------------------------------------
def button_move(self, event):
'''Handle dragging of an object'''
# set movement amount
delta_x = 15
delta_y = 15
# move the object the appropriate amount
#self.canvas.move(self._drag_data["item"], delta_x, delta_y)
self.canvas.move(self._drag_data[1], delta_x, delta_y)
# record the new position
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 :(得分:1)
command=
执行没有event
的函数,但您指定的函数需要event
- command=self.button_move
- &gt; def button_move(self, event)
但bind
与event
执行相同的功能,因此您需要使用此event
函数。
解决方案:使用事件的默认值,即None
def button_move(self, event=None):
但如果您使用event.x
event.y
,command=
答案 1 :(得分:0)
以下是使用furas建议的更新代码:
import Tkinter as tk
class Example(tk.Frame):
'''Illustrate how to drag items on a Tkinter canvas'''
def __init__(self, parent):
tk.Frame.__init__(self, parent)
# create a canvas
self.canvas = tk.Canvas(width=400, height=400)
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}
# create a couple of movable objects
self._create_token((100, 100), "white")
self._create_token((200, 100), "black")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
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)
#-----------------------------------------------------------------------------
self.canvas.button2 = tk.Button(self.canvas, text="Button Test",
command=self.button_move)
self.canvas.button2.config(bg="cyan",fg="black")
self.canvas.button2.pack(side='top')
self.canvas.tag_bind("button2", "<ButtonPress-1>", self.button_move)
#-----------------------------------------------------------------------------
def _create_token(self, coord, color):
'''Create a token at the given coordinate in the given 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):
'''Begining 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 on_token_release(self, event):
'''End drag of an object'''
# reset the drag information
self._drag_data["item"] = None
self._drag_data["x"] = 0
self._drag_data["y"] = 0
def on_token_motion(self, event):
'''Handle dragging of an object'''
# compute how much the mouse 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
#-----------------------------------------------------------------------------
def button_move(self, event=None):
'''Handle dragging of an object'''
# set movement amount
delta_x = 15
delta_y = 15
# move the object the appropriate amount
#self.canvas.move(self._drag_data["item"], delta_x, delta_y)
#self.canvas.move(self._drag_data[1], delta_x, delta_y)
self.canvas.move(1, delta_x, delta_y) # moves item 1, when cursor is over token
# record the new position
#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()
答案 2 :(得分:0)
当您将button_move()
之类的回调配置为按钮的command
时,调用它时唯一的参数是self
,就像您这样调用它一样:< / p>
self.button_move()
但由于button_move()
还需要event
参数,因此会出现以下错误:
TypeError: button_move() takes exactly 2 arguments (1 given).
因此,从event
定义中移除button_move()
参数将是第一步。
此外,由于event
不在button_move()
范围内,您应该删除这两行:
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
最后,您需要要移动的画布对象的id才能使self.canvas.move()
行生效。我建议你删除这行
self._drag_data["item"] = None
来自on_token_release()
的,以便上次点击的画布对象中的id保存在self._drag_data["item"]
中。然后,您需要做的就是在尝试拨打self._drag_data["item"]
之前检查canvas.move()
是否不是。
应用所有这些更改会产生以下代码:
import Tkinter as tk
class Example(tk.Frame):
'''Illustrate how to drag items on a Tkinter canvas'''
def __init__(self, parent):
tk.Frame.__init__(self, parent)
# create a canvas
self.canvas = tk.Canvas(width=400, height=400)
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}
# create a couple of movable objects
self._create_token((100, 100), "white")
self._create_token((200, 100), "black")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
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)
self.canvas.button2 = tk.Button(self.canvas, text="Button Test",
command=self.button_move)
self.canvas.button2.config(bg="cyan",fg="black")
self.canvas.button2.pack(side='top')
self.canvas.tag_bind("button2", "<ButtonPress-1>", self.button_move)
def _create_token(self, coord, color):
'''Create a token at the given coordinate in the given 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):
'''Begining 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 on_token_release(self, event):
'''End drag of an object'''
# reset the drag information
self._drag_data["x"] = 0
self._drag_data["y"] = 0
def on_token_motion(self, event):
'''Handle dragging of an object'''
# compute how much the mouse 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
def button_move(self):
if not self._drag_data["item"]:
return
'''Handle dragging of an object'''
# set movement amount
delta_x = 15
delta_y = 15
# move the object the appropriate amount
#self.canvas.move(self._drag_data["item"], delta_x, delta_y)
self.canvas.move(self._drag_data["item"], delta_x, delta_y)
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()