Clearing All Labels from a Tkinter Window

Clearing all Labels from a tkinter window

As PM 2Ring suggested it is usually useful to append labels to a list for future ref:

tmp = Label(...)
labels.append(tmp)

then just:

foreach label in labels: label.destroy()

If you do not want a list, and you're sure you want to clear everything in root:

foreach label in root.children.values(): label.destroy()

The children dict always holds the objects contained within. If you want to keep the map label, you will have to make your own list as I showed, without appending info into it.

How to delete all labels from frame but keep menu/buttons? tkinter, python

Since, the lables are all you want to destroy, you can write the delete function like this:

def delete(): 
for label in mainframe.winfo_children():
if type(label) == Label : # just Label since you used a wildcard import to import tkinter
label.destroy()

what happens here is that the function checks whether the widget to be destroyed is a label and if it is, the widget is destroyed. Here is a sample code to show you how it works

from tkinter import *


def delete():
for label in mainframe.winfo_children():
if type(label) == Label :
label.destroy()

root = Tk()

mainframe = Frame(root)
mainframe.pack()
lbl1 = Label(mainframe,text="hello")
lbl1.pack()
lbl2 = Label(mainframe,text="hello")
lbl2.pack()
btn1 = Button(mainframe,text="Button")
btn1.pack()
btn2 = Button(mainframe,text="Button")
btn2.pack()
delete()

root.mainloop()

on running this piece of code, you will notice that the lables are deleted but the buttons stay on the screen.
So your completed code should look something like this

from tkinter import *
from openpyxl.workbook import Workbook
from openpyxl import load_workbook
import random

root = Tk()
root.title("The Book of Wisdom")
root.geometry("800x450")

wb = load_workbook('Book_of_Wisdom.xlsx')
ws = wb.active

mainframe = Frame(root)
mainframe.pack(padx= 10, pady= 10)
Main_Label = Label(mainframe, text="Book of Wisdom", font=("Day Roman", 35))
Main_Label.pack()

clicked = StringVar(root)
choices = {'Prideful','Doubtful','Scared', 'Anxious', 'Bullied'}
clicked.set('Choose Emotion')

def delete():
for label in mainframe.winfo_children():
if type(label) == Label :
label.destroy()

# DROP DOWN MENU vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
dropDownMenu = OptionMenu(mainframe, clicked, *choices)
Label(mainframe, text="How are you feeling?").pack()
dropDownMenu.pack()

def change_dropdown(*args):
global Prideful_label
global Doubtful_label
global Scared_label
global Anxious_label
global Bullied_label

Prideful = ws['A2'].value, ws['A3'].value, ws['A4'].value, ws['A5'].value, ws['A6'].value, ws['A7'].value
rand_Prideful = random.choice(Prideful)

Doubtful = ws['B2'].value, ws['B3'].value, ws['B4'].value, ws['B5'].value, ws['B6'].value, ws['B7'].value, ws['B8'].value
rand_Doutful = random.choice(Doubtful)

Scared = ws['C2'].value, ws['C3'].value, ws['C4'].value, ws['C5'].value
rand_Scared = random.choice(Scared)

Anxious = ws['D2'].value, ws['D3'].value, ws['D4'].value, ws['D5'].value
rand_Anxious = random.choice(Anxious)

Bullied = ws['E2'].value, ws['E3'].value, ws['E4'].value, ws['E5'].value
rand_Bullied = random.choice(Bullied)

Prideful_label = Label(mainframe, text= rand_Prideful)
Doubtful_label = Label(mainframe, text= rand_Doutful)
Scared_label = Label(mainframe, text=rand_Scared)
Anxious_label = Label(mainframe, text=rand_Anxious)
Bullied_label = Label(mainframe, text=rand_Bullied)

if clicked.get() == 'Prideful':
Prideful_label.pack()
elif clicked.get() == 'Doubtful':
Doubtful_label.pack()
elif clicked.get() == 'Scared':
Scared_label.pack()
elif clicked.get() == 'Anxious':
Anxious_label.pack()
elif clicked.get() == 'Bullied':
Bullied_label.pack()

clicked.trace('w', change_dropdown)
# DROP DOWN MENU ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clearButton = Button(mainframe, text = "Clear", command = delete)
clearButton.pack(padx = 50, pady = 50)

root.mainloop()

How can i delete all labels from my frame without deleting the frame itself?

The problem with your code is in what you're saving to active_labels. If you examine it, you'll see it's nothing but a list of None values. That is because Label(...).place(...) always returns None.

The first step is to separate widget creation and widget layout, so that your active_labels list accurately contains all of the labels. Then, you can delete them in your loop by calling destroy on each label:

for label in active_labels:
label.destroy()

The other solution is to not worry about maintaining a list. Any widget can return a list of its children, so you can simply loop over that list:

for label in page2.winfo_children():
label.destroy()

Note: this assumes that you're actually putting the labels in page2, and haven't made the same mistake and page2 is set to None.

How to delete or destroy Label in tkinter?

In the code you have provided I believe the fix you are looking for is to change this:

label.after(1000 , lambda: label.destroy())

To this:

label.after(1000, label.master.destroy)

You need to destroy label.master (I am guessing this is actually a root window) because if you do not then you end up with a big box on the screen that is not transparent.

That said I am not sure why you are writing your app in this way. I guess it works and I was not actually aware you could do this but still I personally would write it using a root window to work with.

import tkinter as tk

root = tk.Tk()


label = tk.Label(root, text='Text on the screen',
font=('Times New Roman','80'), fg='black', bg='white')
label.pack()

root.overrideredirect(True)
root.geometry("+250+250")
root.wm_attributes("-topmost", True)
root.wm_attributes("-disabled", True)
root.wm_attributes("-transparentcolor", "white")

root.after(1000, root.destroy)

root.mainloop()

Python tkinter removing label after 2 seconds

Attempt to do

root.after(2000, lambda: warnlabel.destroy())

Try using it without lambda.

And also change

warnlabel = Label(root, text="MUST ENTER ALL 3").grid(row=1, column=3)

To this

warnlabel = Label(root, text="MUST ENTER ALL 3")
warnlabel.grid(row=1, column=3)

How to clear the tkinter label in loop and how to terminate the loop upon clicking another button

You should create empty label at start and later only change text in existing label

 label2.config(text=random.choice(name_list))

or

 label2["text"] = random.choice(name_list))

When you press button then you could run function which change both values flag1 and flag2 (one set True and other set False) and after that run function which will run loop using after()

And you have to use global to set external variables. Without global you create local variables.

You could use more readable names running_1, running_2 instead of flag1, flag2 and use values True/False instead of 0/1

And instead of msvcrt you can use root.bind("<Return>", stop) to run function stop() which will set running_1 = False and running_2 = False to stop all loop.s


Minimal working code

BTW: I use 500 in after() to slowdown it and see what values it displays.

import tkinter as tk
import random

# --- functions

def printing_1():
global running_1
global running_2
global name_list

running_1 = True
running_2 = False # stop other list
name_list = ['Rui Sagar' , 'Nana Kana', 'Mike', 'Bob', 'Drake']

print("start list 1")
update_1()

def update_1():
if running_1:
label["text"] = random.choice(name_list)
root.after(500, update_1)

def printing_2():
global running_1
global running_2
global name_list

running_1 = False # stop other list
running_2 = True
name_list = ['Mia Jennete Moi' , 'cara', 'juili', 'meera', 'ed']

print("start list 2")
update_2()

def update_2():
if running_2:
label["text"] = random.choice(name_list)
root.after(500, update_2)

def stop(event):
global running_1
global running_2

running_1 = False
running_2 = False

print('stoped')

# --- main ---

running_1 = False
running_2 = False
name_list = None

root = tk.Tk()

root.bind('<Return>', stop)

canvas = tk.Canvas(root, width=500, height=200)
canvas.pack()

w = tk.Canvas(root, width=500, height=200)
w.place(relx=0.5, rely=0.1)

label = tk.Label(root)
w.create_window(60, 40, window=label)

button1 = tk.Button(root, text="Option 1", command=printing_1)
canvas.create_window(40, 30, window=button1)

button2 = tk.Button(root, text="Option 2", command=printing_2)
canvas.create_window(40, 80, window=button2)

root.mainloop()

EDIT:

You can also reduce to use only one running and one function update_label().

I check if running is True then I don't run new loop but it will automatically use already running loop but with new name_list

import tkinter as tk
import random

# --- functions

def printing_1():
global name_list
global running

name_list = ['Rui Sagar' , 'Nana Kana', 'Mike', 'Bob', 'Drake']

if not running:
running = True
update_label()

def printing_2():
global name_list
global running

name_list = ['Mia Jennete Moi' , 'cara', 'juili', 'meera', 'ed']

if not running:
running = True
update_label()

def update_label():

if running:
label["text"] = random.choice(name_list)
root.after(500, update_label)

def stop(event):
global running

running = False

print('stoped')

# --- main ---

name_list = None
running = False

root = tk.Tk()

root.bind('<Return>', stop)

canvas = tk.Canvas(root, width=500, height=200)
canvas.pack()

w = tk.Canvas(root, width=500, height=200)
w.place(relx=0.5, rely=0.1)

label = tk.Label(root)
w.create_window(60, 40, window=label)

button1 = tk.Button(root, text="Option 1", command=printing_1)
canvas.create_window(40, 30, window=button1)

button2 = tk.Button(root, text="Option 2", command=printing_2)
canvas.create_window(40, 80, window=button2)

root.mainloop()

EDIT:

If you want to update label only when when you press key then you don't need msvcrt and after but only bind('<Key>', function_name)

import tkinter as tk
import random

# --- functions

def printing_1():
"""Assign new list and update label"""
global name_list

name_list = ['Rui Sagar' , 'Nana Kana', 'Mike', 'Bob', 'Drake']

# set value at start
update_label()

def printing_2():
"""Assign new list and update label"""
global name_list

name_list = ['Mia Jennete Moi' , 'cara', 'juili', 'meera', 'ed']

# set value at start
update_label()

def on_key(event):
"""Update label if list is assigned to `name_list`
and pressed key is different then `Return`"""
if name_list and event.keysym != 'Return':
update_label()

def update_label():
label["text"] = random.choice(name_list)

# --- main ---

name_list = None

root = tk.Tk()
root.bind('<Key>', on_key) # run function when pressed any key

canvas = tk.Canvas(root, width=500, height=200)
canvas.pack()

w = tk.Canvas(root, width=500, height=200)
w.place(relx=0.5, rely=0.1)

label = tk.Label(root)
w.create_window(60, 40, window=label)

button1 = tk.Button(root, text="Option 1", command=printing_1)
canvas.create_window(40, 30, window=button1)

button2 = tk.Button(root, text="Option 2", command=printing_2)
canvas.create_window(40, 80, window=button2)

root.mainloop()


Related Topics



Leave a reply



Submit