3

I created a script that dynamically add/remove/updates a label in a window. The only problem I am having is that the old frames labels doesn't disappear.. The problem leads to some label disturbing in the bg of the windows and of course this leads to some kind of memory leak ( not sure if its the proper term 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 screen shots :

3 devices are connected then 3 labels are shown:

3 devices are connected then 3 labels are shown

2 devices are connected then 2 labels are shown:

2 devices are connected then 2 labels are shown

New labels are on top an old ones:

new labels are on top an old ones

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
Ilan.b
  • 583
  • 6
  • 19

1 Answers1

1

Using grid() as your layout mechanism you could use grid_remove or grid_forget to remove your labels. If you want to permanently delete them, use destroy() on the widgets itself.

I would recommend using a more dynamic behaviour. You could use tk.StringVar() ( in that case a list of it -> device_list ) to store your data - and use

lb=tk.Label(self.root, textvariable=device_list[-1])

to display your data. Using this will give you a limited number of Labels and not create a new one for every data field.

The either store your labels in a list to remove them or think of putting your labels in a container (e.g. tk.Frame()) and rebuild this container when reading new data.

Also see this question for advice on deleting widgets.

Community
  • 1
  • 1
R4PH43L
  • 2,122
  • 3
  • 18
  • 30
  • You don't need a `StringVar` to accomplish your recommended method. You _can_, but it isn't required. You can also use the `configure` method of a label to change the displayed value. – Bryan Oakley Jul 13 '15 at 10:50
  • 1
    That is correct Bryan. That is also why i said i would recommend them because i think it is cleaner to use the built in update method instead of accessing the widgets from higher levels when there are such methods available. But you are completely right, it is not necessary, just "the way i prefer". – R4PH43L Jul 13 '15 at 11:13
  • I don't understand the "cleaner" concept. In both cases you have to access a method of an object from higher up. Either you do `widget.configure(...)` or `variable.set(...)`, but in both cases you're having to access another object. I think it's cleaner to have a single object that controls your display rather than two. Regardless, the answer to this question is as you stated -- don't recreate the labels, just update them. – Bryan Oakley Jul 13 '15 at 12:00
  • 1
    With cleaner concept I mean seperation of logic and view model. Sorry if that was not clear. – R4PH43L Jul 14 '15 at 08:54