0

I wanted to delete everything on a canvas. And i thought canvas.delete(tk.ALL) is a good way to go. But its not working. Why? The accelerators are also not working.

 import tkinter as tk

class Graphy(tk.Frame):
    def __init__(self,parent):
        tk.Frame.__init__(self,parent)
        self.parent = parent
        self.parent.title("Graphy 0.1")
        self.initialize()

    def initialize(self):

        #Toolbar
        toolbar = tk.Frame(self.parent)
        toolbar.pack(side=tk.TOP, fill=tk.X)
        knotbtn=tk.Button(toolbar, text="o")
        knotbtn.pack(side=tk.LEFT, padx=2, pady=2)
        edgebtn=tk.Button(toolbar, text="/")
        edgebtn.pack(side=tk.LEFT, padx=2, pady=2)


        #Canvas
        self.canvas = tk.Canvas(self.parent, height=600, width=600, bg="white")
        self.canvas.pack()

        #Menue
        menu = tk.Menu(self.parent)
        self.parent.config(menu=menu)

        filemenu = tk.Menu(menu)
        menu.add_cascade(label="Datei", menu=filemenu)
        filemenu.add_command(label= "Neu", command=self.canvas.delete(tk.ALL), accelerator="Strg+N")
        filemenu.add_separator()
        filemenu.add_command(label="Beenden", command=root.quit, accelerator="Strg+Q")

        sightmenu = tk.Menu(menu)
        menu.add_cascade(label="Ansicht", menu=sightmenu)
        sightmenu.add_command(label="Farbe waehlen")

        helpmenu = tk.Menu(menu)
        menu.add_cascade(label="Hilfe", menu=helpmenu)
        helpmenu.add_command(label="Ueber")

        root.bind_all("<Ctrl-N>",self.canvas.delete(tk.ALL))
        root.bind_all("<Ctrl-Q>",root.quit())

        self.state = 0
        self.selected = None
        self.start_x = 0
        self.start_y = 0

        def newKnotornewEdge(event):
            #if button "o" is pressed, every click on the canvas results in a circle
            if self.state == 0:
                self.canvas.create_oval(event.x-25,event.y-25,event.x+25, event.y+25, fill="blue")
                self.canvas.create_text(event.x, event.y, text="A", fill="white")
            #if button "/" is pressed, and two circles are selected, draw a line between them
            elif self.state == 1:
                if self.canvas.itemcget(self.canvas.find_overlapping(event.x, event.y, event.x, event.y), "fill") == "blue" and self.selected == None:
                    self.selected = 1
                    self.start_x = event.x
                    self.start_y = event.y
                elif self.canvas.itemcget(self.canvas.find_overlapping(event.x, event.y, event.x, event.y), "fill") == "blue" and self.selected == 1:
                    self.canvas.create_line(self.start_x, self.start_y, event.x, event.y)
                    self.selected = None
                    self.start_x = 0
                    self.start_y = 0
                elif self.canvas.itemcget(self.canvas.find_overlapping(event.x, event.y, event.x, event.y), "fill") != "blue" and self.selected == 1:
                    self.selected = None
                    self.start_x = 0 
                    self.start_y = 0                     
        self.canvas.bind("<Button -1>", newKnotornewEdge)


        def knotbtnclick(event):
            knotbtn.config(relief = tk.SUNKEN, state=tk.DISABLED)
            edgebtn.config(relief = tk.RAISED, state=tk.ACTIVE)
            self.state = 0
        knotbtn.bind("<Button-1>", knotbtnclick)


        def edgebtnclick(event):
            knotbtn.config(relief = tk.RAISED, state=tk.ACTIVE)
            edgebtn.config(relief = tk.SUNKEN, state=tk.DISABLED)
            self.state = 1
        edgebtn.bind("<Button-1>", edgebtnclick)


root = tk.Tk()
app = Graphy(root)

root.mainloop()
buttercup
  • 3
  • 3
  • `canvas.delete()` then recreate canvas if you still need it. Any time you delete a container in tkinter you also delete all of its content. – Mike - SMT Jul 03 '18 at 12:38
  • @Mike-SMT A canvas has a [`delete` method](http://effbot.org/tkinterbook/canvas.htm#Tkinter.Canvas.delete-method) to delete items. using `canvas.delete(tk.ALL)` or `canvas.delete('all')` will delete all items on the canvas. The problem here is that it isn't called when the menu item is clicked because the `command` parameter is wrong. – fhdrsdg Jul 03 '18 at 12:54
  • @fhdrsdg ya I see that. The quick fix is to change `command=self.canvas.delete(tk.ALL)` to `command=lambda: self.canvas.delete(tk.ALL)`. But this should be closed as a duplicate seeing that this kind of problem has been raised many many times. – Mike - SMT Jul 03 '18 at 13:25
  • Thanks for your help @fhdrsdg. it wasn't my intention to post a duplicate but i searched a lot and found nothing. Do you also have an idea why my shortcurts are not working? Its not because of the same reason i think – buttercup Jul 03 '18 at 13:37
  • also thanks for your help @Mike-SMT =) – buttercup Jul 03 '18 at 13:38
  • No problem, we see this problem a lot so we quickly recognize it as a duplicate, but it can be hard to spot since it manifests itself in so many different ways (depending on what the command should do). The shortcuts actually have the same problem (along with a wrong event format). Use `root.bind_all("",lambda e: self.canvas.delete(tk.ALL))` and `root.bind_all("",lambda e: root.destroy())` – fhdrsdg Jul 03 '18 at 13:49
  • @fdhrsdg thanks, that helped me a lot =) – buttercup Jul 03 '18 at 14:32

0 Answers0