如何使用 tkinter python 将整个内容拖动到矩形中?
how to drag entire contents in a rectangle using tkinter python?
在输出画面上,如果我拖动外边的矩形,就会有一个矩形包围在一个矩形里面
内部矩形也应该被拖动,但只有外部矩形被拖动。应该如何拖动外部矩形中的全部内容?。在任何形状中,如果形状被拖动,其中的内容也应该被拖动,但内容不会被拖动,只有外部形状被拖动。
这是我的代码。
import tkinter as tk # python 3
# import Tkinter as tk # python 2
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, background="bisque")
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(50, 100, "white")
self.create_token(200, 100, "black")
self.create_token1(200,100,"white")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
self.canvas.tag_bind("token", "<ButtonPress-1>", self.drag_start)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.drag_stop)
self.canvas.tag_bind("token", "<B1-Motion>", self.drag)
def create_token(self, x, y, color):
"""Create a token at the given coordinate in the given color"""
self.canvas.create_rectangle(
x - 25,
y - 25,
x + 25,
y + 25,
outline=color,
fill=color,
tags=("token",),
)
def create_token1(self,x,y,color):
self.canvas.create_rectangle(
x - 25,
y - 10,
x + 25,
y + 10,
outline=color,
fill=color,
tags=("token",),
)
def drag_start(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 drag_stop(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 drag(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
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
在 drag_start()
中,我使用外部矩形来获取它的区域,并将标签 "drag" 添加到完全位于该区域内的所有元素
rect = self.canvas.bbox(self._drag_data["item"])
self.canvas.addtag_enclosed("drag", *rect)
在 dra()
中,我移动了带有标签 "drag"
的所有元素
self.canvas.move("drag", delta_x, delta_y)
在 drag_stop()
中,我从所有具有标签 "drag"
的元素中删除标签 "drag"
self.canvas.dtag("drag", "drag")
这样外矩形也可以移动内矩形。但是,如果您移动内部矩形,则内部矩形不会移动。如果你在移动内部矩形时想要外部矩形,那么也许你应该使用标签 "token"
self.canvas.move("token", delta_x, delta_y)
import tkinter as tk # python 3
# import Tkinter as tk # python 2
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, background="bisque")
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(50, 100, "white")
self.create_token(200, 100, "black")
self.create_token1(200,100,"white")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
self.canvas.tag_bind("token", "<ButtonPress-1>", self.drag_start)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.drag_stop)
self.canvas.tag_bind("token", "<B1-Motion>", self.drag)
def create_token(self, x, y, color):
"""Create a token at the given coordinate in the given color"""
self.canvas.create_rectangle(
x - 25,
y - 25,
x + 25,
y + 25,
outline=color,
fill=color,
tags=("token",),
)
def create_token1(self,x,y,color):
self.canvas.create_rectangle(
x - 25,
y - 10,
x + 25,
y + 10,
outline=color,
fill=color,
tags=("token",),
)
def drag_start(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]
rect = self.canvas.bbox(self._drag_data["item"])
self.canvas.addtag_enclosed("drag", *rect)
print(rect)
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
def drag_stop(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
self.canvas.dtag("drag", "drag")
def drag(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)
self.canvas.move("drag", 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()
对前面示例的这些小改动防止不可撤销地将对象拖出 canvas(主要参见拖动功能)。并感谢前面的示例。
import tkinter as tk # python 3
# import Tkinter as tk # python 2
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(self,width=400, height=400, background="bisque")
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(50, 100, "white")
self.create_token(200, 100, "black")
self.create_token1(200,100,"white")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
self.canvas.tag_bind("token", "<ButtonPress-1>", self.drag_start)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.drag_stop)
self.canvas.tag_bind("token", "<B1-Motion>", self.drag)
def create_token(self, x, y, color):
"""Create a token at the given coordinate in the given color"""
self.canvas.create_rectangle(
x - 25,
y - 25,
x + 25,
y + 25,
outline=color,
fill=color,
tags=("token",),
)
def create_token1(self,x,y,color):
self.canvas.create_rectangle(
x - 20,
y - 10,
x + 20,
y + 5,
outline=color,
fill=color,
tags=("token",),
)
def drag_start(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]
rect = self.canvas.bbox(self._drag_data["item"])
self.canvas.addtag_enclosed("drag", *rect)
print(rect)
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
def drag_stop(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
self.canvas.dtag("drag", "drag")
def drag(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"]
w=self.winfo_width()
h=self.winfo_height()
rect = self.canvas.bbox(self._drag_data["item"])
if 0:
##don't allow any part of items to move off the canvas
if rect[3]+delta_y > h: delta_y=0 #stop down
if rect[1]+delta_y < 0: delta_y=0 #stop up
if rect[2]+delta_x > w: delta_x=0 #stop right
if rect[0]+delta_x < 0: delta_x=0 #stop down
else:
##don't allow the last 10 pixels to move off the canvas
pixels=10
if rect[1]+delta_y+pixels > h: delta_y=0 #stop down
if rect[3]+delta_y-pixels < 0: delta_y=0 #stop up
if rect[0]+delta_x+pixels > w: delta_x=0 #stop right
if rect[2]+delta_x-pixels < 0: delta_x=0 #stop down
# move the object the appropriate amount
#self.canvas.move(self._drag_data["item"], delta_x, delta_y)
self.canvas.move("drag", 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()
root.geometry("800x500")
#Example(root).pack(fill="both", expand=True)
Example(root).place(relx=0.1,rely=0.1,relwidth=0.8,relheight=0.8)
root.mainloop()
在输出画面上,如果我拖动外边的矩形,就会有一个矩形包围在一个矩形里面 内部矩形也应该被拖动,但只有外部矩形被拖动。应该如何拖动外部矩形中的全部内容?。在任何形状中,如果形状被拖动,其中的内容也应该被拖动,但内容不会被拖动,只有外部形状被拖动。
这是我的代码。
import tkinter as tk # python 3
# import Tkinter as tk # python 2
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, background="bisque")
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(50, 100, "white")
self.create_token(200, 100, "black")
self.create_token1(200,100,"white")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
self.canvas.tag_bind("token", "<ButtonPress-1>", self.drag_start)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.drag_stop)
self.canvas.tag_bind("token", "<B1-Motion>", self.drag)
def create_token(self, x, y, color):
"""Create a token at the given coordinate in the given color"""
self.canvas.create_rectangle(
x - 25,
y - 25,
x + 25,
y + 25,
outline=color,
fill=color,
tags=("token",),
)
def create_token1(self,x,y,color):
self.canvas.create_rectangle(
x - 25,
y - 10,
x + 25,
y + 10,
outline=color,
fill=color,
tags=("token",),
)
def drag_start(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 drag_stop(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 drag(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
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()
在 drag_start()
中,我使用外部矩形来获取它的区域,并将标签 "drag" 添加到完全位于该区域内的所有元素
rect = self.canvas.bbox(self._drag_data["item"])
self.canvas.addtag_enclosed("drag", *rect)
在 dra()
中,我移动了带有标签 "drag"
self.canvas.move("drag", delta_x, delta_y)
在 drag_stop()
中,我从所有具有标签 "drag"
"drag"
self.canvas.dtag("drag", "drag")
这样外矩形也可以移动内矩形。但是,如果您移动内部矩形,则内部矩形不会移动。如果你在移动内部矩形时想要外部矩形,那么也许你应该使用标签 "token"
self.canvas.move("token", delta_x, delta_y)
import tkinter as tk # python 3
# import Tkinter as tk # python 2
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, background="bisque")
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(50, 100, "white")
self.create_token(200, 100, "black")
self.create_token1(200,100,"white")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
self.canvas.tag_bind("token", "<ButtonPress-1>", self.drag_start)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.drag_stop)
self.canvas.tag_bind("token", "<B1-Motion>", self.drag)
def create_token(self, x, y, color):
"""Create a token at the given coordinate in the given color"""
self.canvas.create_rectangle(
x - 25,
y - 25,
x + 25,
y + 25,
outline=color,
fill=color,
tags=("token",),
)
def create_token1(self,x,y,color):
self.canvas.create_rectangle(
x - 25,
y - 10,
x + 25,
y + 10,
outline=color,
fill=color,
tags=("token",),
)
def drag_start(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]
rect = self.canvas.bbox(self._drag_data["item"])
self.canvas.addtag_enclosed("drag", *rect)
print(rect)
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
def drag_stop(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
self.canvas.dtag("drag", "drag")
def drag(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)
self.canvas.move("drag", 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()
对前面示例的这些小改动防止不可撤销地将对象拖出 canvas(主要参见拖动功能)。并感谢前面的示例。
import tkinter as tk # python 3
# import Tkinter as tk # python 2
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(self,width=400, height=400, background="bisque")
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(50, 100, "white")
self.create_token(200, 100, "black")
self.create_token1(200,100,"white")
# add bindings for clicking, dragging and releasing over
# any object with the "token" tag
self.canvas.tag_bind("token", "<ButtonPress-1>", self.drag_start)
self.canvas.tag_bind("token", "<ButtonRelease-1>", self.drag_stop)
self.canvas.tag_bind("token", "<B1-Motion>", self.drag)
def create_token(self, x, y, color):
"""Create a token at the given coordinate in the given color"""
self.canvas.create_rectangle(
x - 25,
y - 25,
x + 25,
y + 25,
outline=color,
fill=color,
tags=("token",),
)
def create_token1(self,x,y,color):
self.canvas.create_rectangle(
x - 20,
y - 10,
x + 20,
y + 5,
outline=color,
fill=color,
tags=("token",),
)
def drag_start(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]
rect = self.canvas.bbox(self._drag_data["item"])
self.canvas.addtag_enclosed("drag", *rect)
print(rect)
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
def drag_stop(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
self.canvas.dtag("drag", "drag")
def drag(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"]
w=self.winfo_width()
h=self.winfo_height()
rect = self.canvas.bbox(self._drag_data["item"])
if 0:
##don't allow any part of items to move off the canvas
if rect[3]+delta_y > h: delta_y=0 #stop down
if rect[1]+delta_y < 0: delta_y=0 #stop up
if rect[2]+delta_x > w: delta_x=0 #stop right
if rect[0]+delta_x < 0: delta_x=0 #stop down
else:
##don't allow the last 10 pixels to move off the canvas
pixels=10
if rect[1]+delta_y+pixels > h: delta_y=0 #stop down
if rect[3]+delta_y-pixels < 0: delta_y=0 #stop up
if rect[0]+delta_x+pixels > w: delta_x=0 #stop right
if rect[2]+delta_x-pixels < 0: delta_x=0 #stop down
# move the object the appropriate amount
#self.canvas.move(self._drag_data["item"], delta_x, delta_y)
self.canvas.move("drag", 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()
root.geometry("800x500")
#Example(root).pack(fill="both", expand=True)
Example(root).place(relx=0.1,rely=0.1,relwidth=0.8,relheight=0.8)
root.mainloop()