fernando
fernando

Reputation: 99

Reusing frame widget in canvas after canvas.delete("all") doesn't work

I have created a frame within a canvas where I place checkbuttons with a mouse click. Selecting another radiobutton I run the command canvas.delete("all") to clear the canvas (and the frame with checkbuttons) and then create the frame again to continue placing checkbuttons. The frame gets created, but i can't place the checkbuttons anymore (I get no error messages either). Anybody knows why?

from tkinter import *

root = Tk()
top_canvas = Canvas(root,width=676,height=768, bg='light blue')
top_canvas.pack()

frame = Frame(top_canvas, bg='light grey')
main_frame = top_canvas.create_window(500, 780, height = 1600, width = 600, window = frame)

def place_checkbutton_in_canvas(e):  # order to insert the checkbutton
    xx = e.x
    yy = e.y
    buttons = Checkbutton(frame)
    buttons.place(x=xx, y=yy)

def place_checkbutton():  #to run when checkbutton is selected. Now the checkbutton will be placed where mouse clicked if choose_line is selected
    frame.bind('<Button-1>', place_checkbutton_in_canvas)

def clear_canvas():
    top_canvas.delete("all")
    frame = Frame(top_canvas, bg='magenta')
    main_frame = top_canvas.create_window(500, 780, height=1600, width=600, window=frame)

chosen_option = IntVar()
choose_checkbutton = Radiobutton(root, text = "place checkbutton", variable=chosen_option, value = 1, command = place_checkbutton)
choose_checkbutton.place(x=10, y=10)
clear_button = Radiobutton(root, text = "clear everything", variable=chosen_option, value = 2, command = clear_canvas)
clear_button.place(x=10, y=100)

root.mainloop()

Upvotes: 0

Views: 46

Answers (1)

jizhihaoSAMA
jizhihaoSAMA

Reputation: 12672

There is no need to delete all the items on canvas.You could use a list to save all of the checkbuttons,and use .destroy() to "delete" them:

from tkinter import *

root = Tk()
top_canvas = Canvas(root,width=676,height=768, bg='light blue')
top_canvas.pack()
root.checkbutton_list = [] # initial a list

frame = Frame(top_canvas, bg='light grey')
main_frame = top_canvas.create_window(500, 780, height = 1600, width = 600, window = frame)

def place_checkbutton_in_canvas(e):  # order to insert the checkbutton
    xx = e.x
    yy = e.y
    buttons = Checkbutton(frame)
    buttons.place(x=xx, y=yy)
    root.checkbutton_list.append(buttons) # append the checkbutton to the list

def place_checkbutton():  #to run when checkbutton is selected. Now the checkbutton will be placed where mouse clicked if choose_line is selected
    frame.bind('<Button-1>', place_checkbutton_in_canvas)

def clear_canvas():
    for i in root.checkbutton_list:
        i.destroy() # destroy all the checkbuttons in the list
    root.checkbutton_list = [] # init it again

chosen_option = IntVar()
choose_checkbutton = Radiobutton(root, text = "place checkbutton", variable=chosen_option, value = 1, command = place_checkbutton)
choose_checkbutton.place(x=10, y=10)
clear_button = Radiobutton(root, text = "clear everything", variable=chosen_option, value = 2, command = clear_canvas)
clear_button.place(x=10, y=100)

root.mainloop()

If you really want to use it with .delete(ALL).You need to change the parent container of the checkbutton.I use root.frame to cover the previous frame.Like:

from tkinter import *

root = Tk()
top_canvas = Canvas(root,width=676,height=768, bg='light blue')
top_canvas.pack()

root.frame = Frame(top_canvas, bg='light grey')
main_frame = top_canvas.create_window(500, 780, height = 1600, width = 600, window = root.frame)

def place_checkbutton_in_canvas(e):  # order to insert the checkbutton
    xx = e.x
    yy = e.y
    buttons = Checkbutton(root.frame)
    buttons.place(x=xx, y=yy)

def place_checkbutton():  #to run when checkbutton is selected. Now the checkbutton will be placed where mouse clicked if choose_line is selected
    root.frame.bind('<Button-1>', place_checkbutton_in_canvas)

def clear_canvas():
    top_canvas.delete("all")
    root.frame = Frame(top_canvas, bg='magenta')
    main_frame = top_canvas.create_window(500, 780, height=1600, width=600, window=root.frame)

chosen_option = IntVar()
choose_checkbutton = Radiobutton(root, text = "place checkbutton", variable=chosen_option, value = 1, command = place_checkbutton)
choose_checkbutton.place(x=10, y=10)
clear_button = Radiobutton(root, text = "clear everything", variable=chosen_option, value = 2, command = clear_canvas)
clear_button.place(x=10, y=100)

root.mainloop()

Upvotes: 1

Related Questions