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
How to Retrieve Data from Dynamic Table - Selenium Python
How to Resolve Modulenotfounderror: No Module Named 'Google.Colab'
Python: Getting Around Division by Zero
Django Rest Framework Csrf Failed: Csrf Cookie Not Set
How to Get Local Issuer Certificate When Using Requests in Python
How to Get the Amount of Consecutive Sub Strings of an Object in a List
Count Frequency of Words in a List and Sort by Frequency
Efficient Date Range Overlap Calculation
How to Check the Date Is Empty Using Python
How to Split Vector into Columns - Using Pyspark
Combine Year, Month and Day in Python to Create a Date
Visual Studio Code Windows , Python Pandas . No Module Named Pandas
How to Compute Mean() for Particular Column in Pandas Dataframe Without Considering Nan Values
How to Crop the Black Background of the Image Using Opencv in Python
Checking If a Pair of Value Is Inside a 2D Array Python
Grab a Number After a String in a File