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:

3 devices are connected then 3 labels are shown

2 devices are connected, then 2 labels are displayed:

2 devices are connected then 2 labels are shown

The new labels are on top of the old ones:

new labels are on top an old ones

+3


source to share


1 answer


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.

+1


source







All Articles