Python 根据字典记录值动态添加、隐藏或忘记Tkinter帧?

Python 根据字典记录值动态添加、隐藏或忘记Tkinter帧?,python,user-interface,dictionary,tkinter,event-handling,Python,User Interface,Dictionary,Tkinter,Event Handling,我正在构建一个GUI应用程序来监视/控制远程嵌入式客户端设备。每个客户端的状态机都在主词典中维护,并在GUI中表示为笔记本小部件中的选项卡(框架)实例。每当新客户机注册时,我想实例化一个选项卡(在我的应用程序中定义为类),当客户机链接超时时隐藏或忘记该选项卡。如果/当客户端重新注册时,我将重新实例化 一般来说,我对Python、Tkinter和OO都是新手,正在为程序结构而挣扎。我需要不断循环字典记录以刷新GUI,但我得出结论,我不能在root.mainloop()结构中进行迭代。因此,状态机字

我正在构建一个GUI应用程序来监视/控制远程嵌入式客户端设备。每个客户端的状态机都在主词典中维护,并在GUI中表示为笔记本小部件中的选项卡(框架)实例。每当新客户机注册时,我想实例化一个选项卡(在我的应用程序中定义为类),当客户机链接超时时隐藏或忘记该选项卡。如果/当客户端重新注册时,我将重新实例化

一般来说,我对Python、Tkinter和OO都是新手,正在为程序结构而挣扎。我需要不断循环字典记录以刷新GUI,但我得出结论,我不能在root.mainloop()结构中进行迭代。因此,状态机字典记录或元素中的“外部”更改需要在外部刷新相应的GUI笔记本选项卡实例,包括创建和删除我的选项卡类的实例


我相信有一个标准的做法,但我还没有在学习上取得足够的进步来解决这个问题。如果您能给我一些快速建议,让我朝着正确的方向前进,我将不胜感激。

我需要解决三个问题,以使我的解决方案发挥作用:

1) 使用root.after函数启用外部异步事件(例如非tkinter GUI事件)以使用更新方法控制GUI元素。。。谢谢Terry Jan Reedy

2) 作为一种方法,在GUI实例化本身中执行整体字典更新,而不是尝试使用单独的函数处理字典管理。也许这对大多数人来说是显而易见的,但对我来说,这是一个范式转变

3) GUI需要是所有字典元素的类的单个实例化,而不是每个元素的单个实例化

代码剪报如下

def remote_window_mgr():
    remote_window = client_gui()


class client_gui(object):

    def __init__(self):

        self.root = Tk()
        self.root.title('Client Manager')

        # Create main Frame in Window
        main_frame = ttk.Frame(self.root, borderwidth = 5, relief = 'ridge')
        main_frame.grid(column = 0, row = 0, sticky = (N, W, E, S))
        main_frame.columnconfigure(0, weight = 1)
        main_frame.rowconfigure(0, weight = 1)

        # Create Notebook widget to host Client Tabs
        self.tab_frame = ttk.Notebook(main_frame)
        self.tab_frame.grid(column = 1, row = 1)

        self.root.after(1000, func=self.gui_update)
        self.root.mainloop()


    def gui_update(self):

        for client_id in list(Client_Records.keys()):
            # Check for new Client
            if client_id not in list(Client_Tabs.keys()):
                client_data = Client_Records[client_id]
                # Create Client Tab
                self.add_tab(client_id)

        for client_id in list(Client_Tabs.keys()):
            # Check if Client Record has been purged...
            if client_id not in list(Client_Records.keys()):
                # Client Record no longer exists, delete Client Tab
                self.remove_tab(client_id)
                del Client_Tabs[client_id]

        for client_id in list(Client_Tabs.keys()):
            # Refresh client tabs for all active clients
            self.update_tab(client_id)

        self.root.after(1000, func=self.gui_update)

您认为不应该在事件处理程序中连续(或很长)循环是正确的。tkinter的替代方法是使用.after函数。这里有几个例子,包括我的一些。Found。after,包括你的一个例子。这似乎是我需要在GUI对象中刷新的解决方案。。。只需要改变我的范式,在对象内部进行字典管理,而不是像我试图做的那样在外部进行。谢谢很高兴看到有人带着提示跑去解决他的问题。从具有自顶向下控制的传统命令式编程的角度来看,事件循环编程似乎可以向下更新。Twisted包的命名就是为了反映这一点。如果您在使用gui执行其他操作时发现gui\u update将gui锁定的时间过长,您可以分为
update\u new
update\u old
、和
update\u all
,并以循环方式设置下一个gui,总延迟约为1000执行时间。例如,
update\u new
可以以
root结尾。在(0,update\u old)
之后。非常好的洞察力。。。谢谢。我最后一次直接编程是在MC6800汇编和C。。。嵌入式和自上而下。刚刚在OO、Sockets和GUI上加快了速度。;-)谢谢你的帮助。