如何在Tkinter窗口中动态添加/删除/更新标签?

3
我创建了一个脚本,动态地添加/删除/更新窗口中的标签。唯一的问题是旧框架的标签没有消失..这会导致标签在窗口背景中干扰,当然也会导致某种内存泄漏(不确定这里是否使用正确的术语)。
这是我的代码:
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()

这里是一些屏幕截图:
连接了3个设备,则显示3个标签: 3 devices are connected then 3 labels are shown 连接了2个设备,则显示2个标签: 2 devices are connected then 2 labels are shown 新标签在旧标签上方: new labels are on top an old ones
1个回答

1
使用grid()作为您的布局机制,您可以使用grid_removegrid_forget来删除标签。如果您想永久删除它们,请在小部件本身上使用destroy()
我建议使用更动态的行为。您可以使用tk.StringVar()(在这种情况下是其列表 -> device_list)来存储您的数据 - 并使用 lb=tk.Label(self.root, textvariable=device_list[-1]) 来显示您的数据。使用此方法将为您提供有限数量的标签,并且不会为每个数据字段创建新标签。
要么将标签存储在列表中以进行删除,要么考虑将标签放入容器中(例如tk.Frame()),并在读取新数据时重新构建此容器。
还可以参见此question以获取有关删除小部件的建议。

您不需要StringVar来实现推荐的方法。虽然可以使用,但并非必需。您还可以使用标签的configure方法来更改显示的值。 - Bryan Oakley
1
这是正确的,Bryan。这也是我为什么说我会推荐它们的原因,因为我认为使用内置的更新方法比在存在此类方法时从更高级别访问小部件更清洁。但你完全正确,这不是必要的,只是“我喜欢的方式”。 - R4PH43L
我不理解"清洁工"的概念。在这两种情况下,你都需要从更高层次访问对象的方法。无论是widget.configure(...)还是variable.set(...),但在这两种情况下,你都必须访问另一个对象。我认为使用单个对象控制你的显示比使用两个对象更加简洁。无论如何,回答这个问题的答案就像你所说的 - 不要重新创建标签,只需更新它们。 - Bryan Oakley
1
我所说的更清晰的概念是逻辑和视图模型的分离。如果不够清楚,我很抱歉。 - R4PH43L

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接