Verstehe ich nicht. Meine Erläuterung dazu hatte die Performance gar nicht zum Gegenstand. Und: Wieso unpraktisch?dd42 hat geschrieben:@ numerix: gute Idee, aber unpraktisch, und kaum verbesserte performance
Sie dir doch mal meinen Entwurf dazu an - da gefällt mir zwar (noch) längst nicht alles und manches fehlt noch (z.B. Schriftgrößenanpassung, Hinzufügen und Entfernen von Rauten durch den Anwender), aber auf dieser Basis könnte man das ohne weiteres implementieren.
Kurze Erläuterungen zur Bedienung:
- Verschieben ist klar
- Text editieren: Doppelklick zum editieren, danach Einfachklick in die Raute oder <Esc> zum Abschließen
- Zum Verbinden zweier Rauten diese mit der rechten Maustaste markieren
- Zum Entfernen einer Verbindung diese mit der mittleren Maustaste anklicken
Code: Alles auswählen
import Tkinter as tk
class Connection(object):
def __init__(self,table,item1,item2):
self.table = table
self.items = (item1,item2)
for item in self.items:
item.select()
for connection in self.table.connections:
if set((item1,item2)) == set(connection.items):
return # connection already exists -> nothing to do
self.line = self.table.create_line(item1.x,item1.y,item2.x,item2.y,
fill="gray",width=2)
self.table.tag_lower(self.line)
self.table.tag_bind(self.line,"<Enter>",self.enter)
self.table.tag_bind(self.line,"<Leave>",self.leave)
self.table.tag_bind(self.line,"<Button-2>",self.delete)
self.table.connections.append(self)
def enter(self,event):
self.table.config(cursor="X_cursor")
self.table.itemconfig(self.line,width=4)
def leave(self,event):
self.table.config(cursor="")
self.table.itemconfig(self.line,width=2)
def delete(self,event):
self.table.delete(self.line)
self.table.connections.remove(self)
self.table.config(cursor="")
class Rhombus(object):
counter = 0
def __init__(self,table,x,y,size=90,background="yellow",border="blue"):
"""x,y is center of rhombus, size is length of one side in px"""
Rhombus.counter += 1
self.table = table
self.x, self.y = x, y
self.size = size
self.rel = 0.75 # relation width to height of rhombus - may be changed
a = self.size / (self.rel*self.rel+1)**.5
points = [x-a,y,x,y+self.rel*a,x+a,y,x,y-self.rel*a]
self.tag = "rhomb%03i" %Rhombus.counter
self.text = "Double-Click\nto change text!"
self.figure_rhomb = self.table.create_polygon(points,tag=self.tag,
fill=background,outline=border,width=2)
self.figure_text = self.table.create_text(x,y,tag=self.tag,
justify="center",text=self.text)
self.dragged = self.edit_begin = self.edit_end = self.selected = False
self.table.tag_bind(self.tag,"<Button-1>",self.drag)
self.table.tag_bind(self.tag,"<ButtonRelease-1>",self.drop)
self.table.tag_bind(self.tag,"<Enter>",self.enter)
self.table.tag_bind(self.tag,"<Leave>",self.leave)
self.table.tag_bind(self.tag,"<Motion>",self.move)
self.table.tag_bind(self.tag,"<Double-Button-1>",self.edit)
self.table.tag_bind(self.tag,"<Button-3>",self.select)
def enter(self,event):
self.table.config(cursor="hand2")
if not self.selected:
self.table.itemconfig(self.figure_rhomb,width=4)
def leave(self,event):
self.table.config(cursor="")
if not self.selected:
self.table.itemconfig(self.figure_rhomb,width=2)
def drag(self,event):
if self.edit_begin:
self.edit_begin = False
self.edit_end = True
return
self.dragged = True
self.table.tag_raise(self.tag)
self.startx, self.starty = event.x, event.y
def drop(self,event):
if self.dragged:
self.dragged = False
if self.edit_end:
self.exitedit()
def move(self,event):
if self.dragged:
dx, dy = event.x-self.startx, event.y-self.starty
self.table.move(self.tag,dx,dy)
self.startx, self.starty = event.x, event.y
self.x, self.y = self.x+dx, self.y+dy
for connection in self.table.connections:
if self in connection.items:
x1,y1,x2,y2 = self.table.coords(connection.line)
if self == connection.items[0]:
self.table.coords(connection.line,self.x,self.y,x2,y2)
else:
self.table.coords(connection.line,x1,y1,self.x,self.y)
def edit(self,event):
if self.edit_begin: return
self.edit_begin = True
self.editor = tk.Text(self.table,width=12,height=2)
self.editor.delete("0.0","end")
self.editor.insert("0.0",self.text)
self.editor_item = self.table.create_window(self.x,self.y,window=self.editor)
self.editor.bind("<Key-Escape>",self.exitedit)
self.editor.focus_set()
def exitedit(self,event=None):
self.edit_end = False
self.text = self.editor.get("0.0","end").strip()
self.editor.unbind("<Key-Escape>")
self.table.itemconfig(self.figure_text,text=self.text)
self.table.delete(self.editor_item)
def select(self,event=None):
if self.selected:
self.selected = False
self.table.itemconfig(self.figure_rhomb,outlinestipple="")
self.table.itemconfig(self.figure_rhomb,width=2)
if self.table.selection:
self.table.selection = None
else:
self.selected = True
self.table.itemconfig(self.figure_rhomb,outlinestipple="gray75")
if self.table.selection:
connection = Connection(self.table,self,self.table.selection)
self.table.selection = None
else:
self.table.selection = self
class Table(tk.Canvas,object):
def __init__(self,master):
tk.Canvas.__init__(self,master,width=520,height=380,bg="white")
self.pack(expand=True)
self.selection = None # selection for connection
self.connections = []
self.rhombs = []
for n in range(5):
self.rhombs.append(Rhombus(self,80+90*n,70+60*n))
if __name__ == "__main__":
root = tk.Tk()
table = Table(root)
root.mainloop()