Я использую tkinter для создания ориентированного графа. На этом графике я пытаюсь удалить все созданные стрелки или конкретную.
Это код:
from tkinter import *
import math
class Window:
#Constructor
def __init__(self, window, colour="white", width=1000, height=700):
#Set variables
self.width = width
self.height = height
self.colour = colour
self.ligacao = []
#This dictionary is used to keep track of an item being dragged
self._drag_data = {"x": 0, "y": 0, "item": None}
#Create canvas
self.canvas = Canvas(window, bg=self.colour, height=self.height, width=self.width)
self.canvas.pack()
#Add bindings for clicking, dragging and releasing overo any object with the "group_drag" tag
self.canvas.bind("<ButtonPress-1>", self.OnCircleButtonPress)
self.canvas.bind("<ButtonRelease-1>", self.OnCircleButtonRelease)
self.canvas.bind("<B1-Motion>", self.OnCircleMotion)
#This is used to draw particle objects on the canvas, notice the tag that has been added as an attribute
def _create_circle(self, xcoord, ycoord, r, outline, color, tag):
self.circle = self.canvas.create_oval(xcoord - r, ycoord - r, xcoord + r, ycoord + r,
outline=outline, fill=color, tags=tag)
#This is used to draw text on top of the object on the canvas
def _create_text(self, xcoord, ycoord, text, tag):
self.text = self.canvas.create_text(xcoord, ycoord, text=text, tags=tag)
def delete_create(self, event):
self.canvas.delete(self.ligacao)
self._create_arrow(300, 500, event.x, event.y, 25, "black", "item-20")
def _create_arrow(self, x0, y0, x1, y1, r, colour, tag):
delta = math.sqrt(math.pow((y1 - y0), 2) + math.pow((x1 - x0), 2))
if delta != 0:
self.arrow = {"x0": x0 + r * (x1 - x0) / delta, "y0": y0 + r * (y1 - y0) / delta,
"x1": x1 - r * (x1 - x0) / delta, "y1": y1 - r * (y1 - y0) / delta, "tag": tag}
self.ligacao.append(self.canvas.create_line(self.arrow["x0"], self.arrow["y0"], self.arrow["x1"], self.arrow["y1"],
fill=colour, arrow=LAST, tags=tag))
else:
self.arrow = {"x0": x0, "y0": y0, "x1": x1, "y1": y1, "tag": tag}
self.ligacao.append(self.canvas.create_line(x0, y0, x1, y1, arrow=LAST, fill=colour, tags=tag))
return [self.arrow["x0"], self.arrow["y0"], self.arrow["x1"], self.arrow["y1"], self.arrow["tag"]]
#This uses the find_closest method to get store the x and y positions of the nearest item into the dictionary
def OnCircleButtonPress(self, event):
'''Begin drag of an object'''
# record the item and its location
item = self.canvas.find_closest(event.x, event.y)[0]
tags = self.canvas.gettags(item)
for tag in tags:
if tag.startswith("item-"):
break
#print(tag)
self._drag_data["item"] = tag
self._drag_data["x"] = event.x
self._drag_data["y"] = event.y
#This clears the dictionary once the mouse button has been released
def OnCircleButtonRelease(self, event):
'''End drag of an object'''
self.canvas.tag_bind(self.circle, "<ButtonRelease-1>", self.delete_create)
self.canvas.tag_bind(self.text, "<ButtonRelease-1>", self.delete_create)
# reset the drag information
self._drag_data["item"] = None
self._drag_data["x"] = 0
self._drag_data["y"] = 0
#This moves the item as it is being dragged around the screen
def OnCircleMotion(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
class Picture:
#Constructor
def __init__(self, window):
self.window = window
def CircleAndText(self, width=100, height=100, r=50, outline="black", colour="#8BF1F5", text="test", t="item-10"):
self.window._create_circle(width, height, r, outline, colour, t)
self.window._create_text(width, height, text, t)
def ArrowAndText(self, x0, y0, x1, y1, r, colour, text, t="item-20"):
s = self.window._create_arrow(x0, y0, x1, y1, r, colour, t)
self.window._create_text(abs(s[0]-s[2])/2 + min(s[0], s[2]),
abs(s[1]-s[3])/2 + min(s[1], s[3]), text, t)
return s
window = Tk()
window.title("Drag & Drop")
#Create an instance of the window class
main_window = Window(window)
dictionary = {"James": [("Paul", 3), ("Julie", 2), ("Lisa", 1)], "Lisa": [("Paul", 5), ("Antonio", 2)],
"Fabian": [("George", 2), ("Diana", 4), ("Julie", 5)], "Julie": [("Paul", 2), ("Antonio", 1)], "Antonio": [("Mary", 1), ("Diana", 2)]}
r = 25
x_meio = int(main_window.width/2)
y_meio = int(main_window.height/2)
i = 1
j = 1
circulo = []
texto_circulo = []
tag_seta = []
seta = []
texto_seta = []
tag = []
keys = dictionary.keys()
dictionary_len = len(keys)
angulo = 2 * math.pi / dictionary_len
raio_x = x_meio - r
raio_y = y_meio - r
for name in dictionary:
k = x_meio + raio_x*math.cos(angulo*(i-1))
l = y_meio + raio_y*math.sin(angulo*(i-1))
m = x_meio + raio_x*math.cos(angulo*i)
n = y_meio + raio_y*math.sin(angulo*i)
Picture(main_window).CircleAndText(k, l, r, "black", "#8BF1F5", name, "item-%s" % int(i*10))
Picture(main_window).CircleAndText(k, l, r, "black", "#8BF1F5", name, "item-%s" % int(i*10))
Picture(main_window).CircleAndText(k, l, r, "black", "#8BF1F5", name, "item-%s" % int(i*10))
Picture(main_window).ArrowAndText(k, l, m, n, r, "black", name, "item-%s" % int(i * 10))
Picture(main_window).ArrowAndText(k, l, m, n, r, "black", name, "item-%s" % int(i * 10))
i += 1
#Start the animation loop
window.mainloop()
Когда я создаю стрелку, создается список self.ligacao
следующим образом:
def _create_arrow(self, x0, y0, x1, y1, r, colour, tag):
delta = math.sqrt(math.pow((y1 - y0), 2) + math.pow((x1 - x0), 2))
if delta != 0:
self.arrow = {"x0": x0 + r * (x1 - x0) / delta, "y0": y0 + r * (y1 - y0) / delta,
"x1": x1 - r * (x1 - x0) / delta, "y1": y1 - r * (y1 - y0) / delta, "tag": tag}
self.ligacao.append(self.canvas.create_line(self.arrow["x0"], self.arrow["y0"], self.arrow["x1"], self.arrow["y1"],
fill=colour, arrow=LAST, tags=tag))
else:
self.arrow = {"x0": x0, "y0": y0, "x1": x1, "y1": y1, "tag": tag}
self.ligacao.append(self.canvas.create_line(x0, y0, x1, y1, arrow=LAST, fill=colour, tags=tag))
return [self.arrow["x0"], self.arrow["y0"], self.arrow["x1"], self.arrow["y1"], self.arrow["tag"]]
Этот метод используется для удаления одной стрелки и создания другой в новой позиции:
def delete_create(self, event):
self.canvas.delete(self.ligacao)
self._create_arrow(300, 500, event.x, event.y, 25, "black", "item-20")
Когда я использую этот код ниже, я могу удалить толькопоследняя стрелка, освобождая последний кружок или текст, но я хотел бы удалить все стрелки или конкретный, более легкий код, который нужно сделать.
self.canvas.tag_bind(self.circle, "<ButtonRelease-1>", self.delete_create)
self.canvas.tag_bind(self.text, "<ButtonRelease-1>", self.delete_create)
Как я могу использовать функцию tag_bind
иудалить все стрелки или конкретную?