Button, events, Canvas

Fragen zu Tkinter.
Antworten
VinzLaist
User
Beiträge: 13
Registriert: Donnerstag 1. Januar 2015, 22:39

Hallo zusammen,

ich versuche ein Programm zu schreiben das nach "Button" befehlen verschiedene Geometrische 2D Köper in einer Canvas angezeigt.(Das bekomme ich auch soweit hin.)
Die dann aber über events (Mausklick in der Canvas) in ihrer Form z.b Größe verändert werden.
Das folgende Beispiel hat erstmal nur Zwei Button Kreis und Rechteck.

Jetzt weiß ich nicht wie ich es programmieren kann das die Events (Mausklick) immer nur auf den zuletzt ausgelöste Button reagieren.
In meinem Beispiel mit "#" gekennzeichnet würd dann natürlich immer ein Kreis erscheinen nach auslösen des events(Mausklick).
Hätte aber gerne das sowohl der Kreis als auch das Rechteck über events verändert werden kann.

Code: Alles auswählen

from tkinter import Tk, Canvas, Entry, Label, Button, messagebox




def Rechteck(x1=150,y1=150,x2=300,y2=300):
    C.delete(*C.find_all())
    C.create_rectangle(x1,y1,x2,y2,width=20, fill="white")
    
def Kreis(x1=150,y1=150,x2=300,y2=300):
    C.delete(*C.find_all())
    C.create_oval(x1,y1,x2,y2,width=20,fill="white")

def Mausklick(event):
    Rechteck(x1=event.x, y1=event.y)
    #Kreis(x1=event.x, y1=event.y)




H = Tk()
H.title("Einfeldträger mit Streckenlast")

C = Canvas(H, width=400, height=500,bg="red")
C.grid(row=0, column=2, columnspan=2)


C.bind("<Button-1>",Mausklick)

B = Button(text="Rechteck",command=Rechteck)
B.grid(row=0, column=3, sticky="ne")

B = Button(text="Kreis",command=Kreis)
B.grid(row=0, column=3, sticky="e")

H.update()

H.mainloop()
Vielen Dank im Voraus!
BlackJack

@VinzLaist: Man müsste sich halt merken was als letztes gezeichnet wurde und genau das dann wieder zeichnen. Wobei man dann auch einfach von dem bereits gezeichneten die Daten ändern könnte statt *alles* zu löschen und dann neu zu zeichnen.

Auf jeden Fall sollte man das mal ordentlich in einem Objekt kapseln statt Variablen auf Modulebene zu verwenden und auch keine einzelnen Grossbuchstaben für Variablen vergeben. Ansonsten gibt's auch noch ein paar andere Sachen aus dem Style Guide for Python Code an die man sich halten könnte.

Edit:

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
import Tkinter as tk
from functools import partial


class Shape(object):
    
    def __init__(self, shape_name, canvas, coordinates=(150, 150, 300, 300)):
        self.canvas = canvas
        self.id = getattr(self.canvas, 'create_' + shape_name)(
            *coordinates, width=20, fill='white'
        )

    def set_coordinates(self, x, y):
        _, _, x_2, y_2 = self.canvas.coords(self.id)
        self.canvas.coords(self.id, x, y, x_2, y_2)

    def delete(self):
        self.canvas.delete(self.id)


class MainUI(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.canvas = tk.Canvas(self, width=400, height=500, background='red')
        self.canvas.pack(side=tk.LEFT)
        self.canvas.bind('<Button-1>', self.on_mouse_click)
        self.shape = None

        button_frame = tk.Frame(self)
        button = tk.Button(
            button_frame,
            text='Rechteck',
            command=partial(self.create_shape, 'rectangle')
        )
        button.pack(side=tk.TOP, fill=tk.X)
        button = tk.Button(
            button_frame,
            text='Kreis',
            command=partial(self.create_shape, 'oval')
        )
        button.pack(side=tk.TOP, fill=tk.X)
        button_frame.pack(side=tk.LEFT)

    def create_shape(self, shape_name):
        if self.shape is not None:
            self.shape.delete()
        self.shape = Shape(shape_name, self.canvas)

    def on_mouse_click(self, event):
        if self.shape:
            self.shape.set_coordinates(event.x, event.y)


def main():
    root = tk.Tk()
    root.title('Einfeldträger mit Streckenlast')
    main_ui = MainUI(root)
    main_ui.pack()
    root.mainloop()


if __name__ == '__main__':
    main()
Antworten