通过列表框中的条目调用函数的 tkinter 错误

tkinter error calling function through entries in listbox

最近,我尝试制作一个完整的应用程序 window,其侧面板菜单带有单独的框架 运行在 canvas 框架中添加一些功能并提交表单。

但我发现每次单击列表框中的任何条目时,它 运行 都是函数或方法而不清除现有的。

我试过 destroy() 和 forget() 对我不起作用(也许我不知道如何使用它?!,并且 destroy() 函数阻止再次使用该函数,直到我关闭整个应用程序和 运行 再一次!)this is a photo of my problem

这是我的代码:

import tkinter as tk
from tkinter import ttk


class MainWindow() :

    def __init__(self,root):


        # menu left
        self.menu_upper_frame = tk.Frame(root, bg="#dfdfdf")

        self.menu_title_label = tk.Label(self.menu_upper_frame, text="menu title", bg="#dfdfdf")
        self.menu_title_label.pack()

        self.menu_left_container = tk.Frame(root, width=150, bg="#ababab")
        self.menu_left_upper = tk.Frame(self.menu_left_container, width=150, height=150, bg="red")

        self.menu_left_upper.pack(side="top", fill="both", expand=True)

        # create a listbox of items
        self.Lb1 = tk.Listbox(self.menu_left_upper,bg ="red", borderwidth=0, highlightthickness=0 )

        self.Lb1.insert(1, "Python")
        self.Lb1.insert(2, "Perl")
        self.Lb1.insert(3, "C")
        self.Lb1.insert(4, "PHP")
        self.Lb1.insert(5, "JSP")
        self.Lb1.insert(6, "Ruby")

        self.Lb1.bind("<<ListboxSelect>>", self.OnClick )   #return selected item
        self.Lb1.pack(fill="both", expand=True, pady=50 )


        # right area
        self.inner_title_frame = tk.Frame(root, bg="#dfdfdf")

        self.inner_title_label = tk.Label(self.inner_title_frame, text="inner title", bg="#dfdfdf")
        self.inner_title_label.pack()

        self.canvas_area = tk.Canvas(root, width=500, height=400, background="#ffffff")
        self.canvas_area.grid(row=1, column=1)

        # status bar
        self.status_frame = tk.Frame(root)
        self.status = tk.Label(self.status_frame, text="this is the status bar")
        self.status.pack(fill="both", expand=True)

        self.menu_upper_frame.grid(row=0, column=0, rowspan=2, sticky="nsew")
        self.menu_left_container.grid(row=1, column=0, rowspan=2, sticky="nsew")
        self.inner_title_frame.grid(row=0, column=1, sticky="ew")
        self.canvas_area.grid(row=1, column=1, sticky="nsew") 
        self.status_frame.grid(row=2, column=0, columnspan=2, sticky="ew")

        root.grid_rowconfigure(1, weight=1)
        root.grid_columnconfigure(1, weight=1)

    def OnClick(self,event):

        widget = event.widget
        selection = widget.curselection()
        value = widget.get(selection)
        if value == 'Python':
            self.tabtop()




    def tabtop(self):

        self.tabControl = ttk.Notebook(self.canvas_area, width=400)          # Create Tab Control


        self.tab1 = ttk.Frame(self.tabControl)             # Create a tab 
        self.tab2 = ttk.Frame(self.tabControl)
        self.tab3 = ttk.Frame(self.tabControl)
        self.tab4 = ttk.Frame(self.tabControl)
        self.tab5 = ttk.Frame(self.tabControl)

        self.tabControl.add(self.tab1, text='Login data' )      # Add the tab

        self.tabControl.add(self.tab2, text='Permission')
        self.tabControl.add(self.tab3, text='Roles')
        self.tabControl.add(self.tab4, text='Personal data')
        self.tabControl.add(self.tab5, text='Business data')
        self.tabControl.pack(expand=1, fill="both")  # Pack to make visible

        self.l2 = tk.Label(self.tab2, text="label 2").pack()
        self.l3 = tk.Label(self.tab3, text="label 3").pack()


root = tk.Tk()
root.title("Control Panel")
root.style = ttk.Style()
root.style.theme_use("clam")
user = MainWindow(root)

root.mainloop()

如果您真正想问的是如何用新笔记本替换现有笔记本,您只需在旧笔记本上调用destroy()在创建新的之前。

首先,在MainWindow.__init__的某处定义self.tabControlNone。然后,在 tabtop 中,您可以在创建新笔记本之前删除旧笔记本:

def tabtop(self):
    if self.tabControl is not None:
        self.tabControl.destroy()

    ...