Python Forum
[Tkinter] How to erase previous output from the canvas?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] How to erase previous output from the canvas?
#1
I'm tinkering with tkinter. I have this to make a window. It takes an input and displays the input text as output.

def myWindow1():
    window = tkinter.Tk()
    window.title("Get a text input and echo it")
    window.config(bg='light blue')
    window.geometry('640x480')
    # make a frame to take the canvas
    frame=Frame(window,width=400,height=300, bg='lightblue')
    frame.pack(expand=True, fill=BOTH) #.grid(row=0,column=0)

    xscrollbar = Scrollbar(frame, orient=HORIZONTAL, width=20, activebackground='red', )
    yscrollbar = Scrollbar(frame, orient=VERTICAL, width=20, activebackground='green', )
    xscrollbar.pack( side = BOTTOM, fill = X )
    yscrollbar.pack( side = RIGHT, fill = Y )

    #canvas1 = tkinter.Canvas(window, xscrollcommand = xscrollbar.set, yscrollcommand = yscrollbar.set, bg='white', width = 400, height = 300,  relief = 'raised')
    #canvas1.pack()
    canvas1 = tkinter.Canvas(frame, bg='white', width = 400, height = 300,  relief = 'raised')
    canvas1.config(xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set)
    canvas1.pack(padx=10, pady=10)

    label1 = tkinter.Label(frame, text='Echo a text input')
    label1.config(font=('helvetica', 14))
    canvas1.create_window(200, 25, window=label1)

    label2 = tkinter.Label(frame, text='Type your text:')
    label2.config(font=('helvetica', 10))
    canvas1.create_window(200, 100, window=label2)

    entry1 = tkinter.Entry (frame) 
    canvas1.create_window(200, 140, window=entry1)

    def getInput():
        
        msg = entry1.get()
        
        label3 = tkinter.Label(frame, text= 'You entered this text:',font=('helvetica', 10))
        canvas1.create_window(200, 210, window=label3)
        # wraplength is in pixels not characters!!
        #label4 = tkinter.Label(window, text=msg,font=('helvetica', 10, 'bold'), anchor='w', width=35, wraplength=80)
        #label4 = tkinter.Label(frame, text=msg,font=('helvetica', 10, 'bold'), anchor='w', width=55, wraplength=390)
        label4 = tkinter.Label(frame, text=msg,font=('helvetica', 10, 'bold'), anchor='w', wraplength=390)
        #canvas1.update()
        canvas1.create_window(200, 250, window=label4)
        # don't set the y value too high or you won't see the output!
        #canvas1.create_window(200, 320, window=label4)
        
    button1 = tkinter.Button(text='Get the text message', command=getInput, bg='brown', fg='white', font=('helvetica', 9, 'bold'))
    canvas1.create_window(200, 180, window=button1)

    window.mainloop()
For example I enter "Hello world!" I see "Hello world!" as output.

Then I enter "Hi me!" I see 'Hi me!" as output, centred over the previous output, "Hello world!".

How do I erase the previous output before the next output gets written? I tried canvas1.update() but that did not do it.
Reply
#2
to clear canvas:
canvas.delete("all")
Reply
#3
Normally you would not create a canvas and fill it with windows to make a dialog window. Normally you wouldn't use a canvas at all. Typical tkinter dialog code looks more like this:
from tkinter import *
window = Tk()
window.title("My Wubdiw")
window.geometry('350x200')
lbl = Label(window, text="Hello")
lbl.grid(column=0, row=0)
btn = Button(window, text="Click Me")
btn.grid(column=1, row=0)
window.mainloop()
Notice there is no explicit sizing and placement. That is left up to the grid layout manager.

You do need a canvas if you want scrollable content, but even then I would expect the canvas to scroll one window that contains a frame that contains all the controls to be scrolled. This lets you use layout management instead of explicit sizing and positioning. Generally scrolled regions are something you see in controls (long lists, multi-line text entries), not top level windows.

The reason your old label text remains when you enter new text is because the getInput function creates a new label that is drawn in the same place as the old. The first time you call getInput you have one label to display the entered text. The second time it is called you have two labels. If the first label is wider than the second you will see parts of the old label. Either you need to delete the old label, or reconfigure the old label to contain the new text.
Reply
#4
Thanks, but that is a bit of an overkill, wiped out all my other stuff!

I just want to delete label4 before I recreate it.

To do that, I think I need to get the ID of label4, which is an integer.

How can I get label4's ID?

Just guessing, I used ID = 4 for label4 the first time. That worked, the previous text was gone.

To begin with, I made label4, so that getInput() has something to delete:

label4 = tkinter.Label(frame, text= 'Your input will be here after you click the button.',font=('helvetica', 10, 'bold'), anchor='w', wraplength=390)
    canvas1.create_window(200, 250, window=label4)    
I put

canvas1.delete(4)
in getInput() at the beginning. Sure enough, the text I put there in the beginning was gone.

But, the next time that ID did not work, because label4 was deleted. The new label4 probably has an ID that went up by 1.

How can I get the integer ID of label4 each time around?
Reply
#5
Found two solutions in the end, just in case anyone is interested:

1. When an object is created, it's ID is returned, save that:

Quote:the_id = canvas1.create_window(200, 250, window=label4)

then:
Quote:canvas1.delete(the_id)

If you use this in a callback to a function, you need to declare it global:
Quote:global the_id
2. Use a tag:

Quote:canvas1.create_window(200, 250, window=label4, tags="label")

then:
Quote:canvas1.delete("label")

More than 1 object may have the same label, so that allows you to do things to all objects with that tag.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] Resizing image inside Canvas (with Canvas' resize) Gupi 2 25,082 Jun-04-2019, 05:05 AM
Last Post: Gupi
  [Tkinter] output to canvas widget freakbot 2 9,917 Dec-01-2016, 12:24 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020