Ich erstelle eine GUI-Anwendung mit tkinter, und die App benötigt eine CAD-Schnittstelle für die Modellierung, daher habe ich das tkinter-Canvas-Widget dafür verwendet.Verhindern, dass gezoomte tkinter-Canvas-Objekte verschoben/Koordinaten geändert werden
Ich implementierte Methoden zum Verschieben und Zoomen der Zeichenfläche mit einer Maus basierend auf this thread. Das Problem, das ich habe, ist, dass das Zoomen der Leinwand die Koordinaten von Objekten verändert (manchmal ändern sich die Koordinaten von positiv zu negativ). Also, wenn ich ein Rechteck auf der Leinwand mit Hilfe von;
self.canvas.create_rectangle(0, 5, 75, 100, outline="black", fill="blue")
self.canvas.create_text(100,125, anchor="nw", text="Click and drag to move the canvas\nScroll to zoom.")
Dann zoomen oder die Leinwand bewegen und zoomen, und ein weiteres Rechteck zeichnen verwendet;
self.canvas.create_rectangle(75, 5, 200, 100, outline="black", fill="red")
ich erwartet hatte, so etwas zu sehen;
Aber ich bekomme diese statt;
Gibt es trotzdem, dies in tkinter zu beheben?
EDIT
Ich habe meinen Code mit Bryans Antwort aktualisiert. Ich konnte den Skalierungsfaktor im Attribut self.scale
verfolgen, aber der Offset (verfolgt im self.offset
Attribut) ist immer noch falsch. Ich bin nicht in der Lage, den kumulativen Offset vom wiederholten Zoomen zu berechnen. Neue Rechtecke skalieren richtig (Größe), aber der Offset/Ort ist immer noch ausgeschaltet.
Hier ist mein aktueller Code;
import Tkinter as tk
class CAD(tk.Frame):
def __init__(self, root):
tk.Frame.__init__(self, root)
self.scale = 1
self.offset = [0, 0]
self.current_scale = [self.offset[0], self.offset[1], self.scale, self.scale]
self.canvas = tk.Canvas(self, width=400, height=350, background="bisque")
self.canvas.pack()
#Plot on the canvas
self.rect = self.canvas.create_rectangle(0, 5, 75, 100, outline="black", fill="blue")
self.canvas.create_text(100,125, anchor="nw", text="""
Left click and drag to move the canvas
Scroll to zoom
Right click to draw rectangle""")
# Mouse bindings to the canvas
self.canvas.bind("<ButtonPress-1>", self.move_start)
self.canvas.bind("<B1-Motion>", self.move_move)
self.bind_all("<MouseWheel>", self.zoom)
self.canvas.bind("<ButtonPress-3>", self.draw)
# move
def move_start(self, event):
self.canvas.scan_mark(event.x, event.y)
def move_move(self, event):
self.canvas.scan_dragto(event.x, event.y, gain=1)
# zoom
def zoom(self, event):
true_x = self.canvas.canvasx(event.x)
true_y = self.canvas.canvasy(event.y)
if (event.delta > 0):
sc = 1.1
elif (event.delta < 0):
sc = 0.9
self.canvas.scale("all", true_x, true_y, sc, sc)
self.scale *= sc
self.offset = [sum(x) for x in zip(self.offset, [true_x, true_y])]
self.current_scale = [self.offset[0], self.offset[1], self.scale, self.scale]
def draw(self, event):
new_item = self.canvas.create_rectangle(75, 5, 200, 100, outline="black", fill="red")
self.canvas.scale(new_item, *self.current_scale)
if __name__ == "__main__":
root = tk.Tk()
CAD(root).pack(fill="both", expand=True)
root.mainloop()
END EDIT
Ich aktualisiert die Frage mit Ihrer Antwort und dem aktuellen Code, haben aber immer noch Probleme mit der Berechnung des kumulativen Offset. – Khristos