How to add / remove / update labels dynamically in a Tkinter window?
I created a script that dynamically add / remove / update a label on a window. The only problem I am having is that the old frame markers do not disappear. The problem causes some shortcuts to be broken in the bg of windows and of course this leads to some kind of memory leak (not sure if the term is correct here.).
This is my code:
import tkinter as tk
from tkinter.ttk import *
from subprocess import call,Popen,PIPE, STDOUT
class App():
def __init__(self):
self.root = tk.Tk()
self.root.title("devices networks")
self.update_clock()
self.root.mainloop()
def update_clock(self):
i=0
adb_absolute_path = "C:\\Users\\ilan.MAXTECH\\AppData\\Local\\Android\\Sdk\\Platform-tools\\"
# Get the list of connected devices
cmd = adb_absolute_path+"adb.exe devices"
proc = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
device_list = proc.communicate()[0].decode().split("\r\n")
# remove unnecessary text in devices call
device_list.pop(0)
device_list.remove("")
device_list.remove("")
#### not working.... #######
# #erase the old labels ( in case a device has been disconected
# for line in range(10):
# lb = Label(self.root, text="")
# lb.grid(row=1, column=line)
###########################
#print netcfg for each device
for device in device_list:
#get the netcfg for specific device
device_serial = device.split("\t")[0]
cmd = adb_absolute_path + "adb.exe -s " + device_serial + " shell netcfg"
proc = Popen(cmd, shell=True, stdout=PIPE, stderr=STDOUT)
netcfg_output = proc.communicate()[0].decode()
#add a new label to the screen
lb = Label(self.root, text=device_serial+"\n"+netcfg_output)
lb.grid(row=1, column=i)
lbblank = Label(self.root,text="\t\t")
lbblank.grid(row=1, column=i+1)
i += 2
self.root.geometry(str(device_list.__len__()*450)+"x700")
self.root.after(1000, self.update_clock)
app=App()
Here are some screenshots:
3 devices are connected, then 3 labels are displayed:
2 devices are connected, then 2 labels are displayed:
The new labels are on top of the old ones:
source to share
Using grid()
as a layout engine, you can use grid_remove
or grid_forget
to remove your labels. If you want to permanently remove them, use destroy()
in the widgets themselves.
I would recommend using a more dynamic behavior. You can use tk.StringVar()
(in this case its a list -> device_list
) to store your data - and use
lb=tk.Label(self.root, textvariable=device_list[-1])
to display your data. By using this, you will get a limited number of labels and not create a new one for each data field.
Keep the labels in a list to remove them, or consider putting your labels in a container (for example tk.Frame()
) and rebuilding that container when reading new data.
Also see this question for tips on removing widgets.
source to share