首页 > 解决方案 > Tkinter 错误,_tkinter.TclError:无法删除 Tcl 命令

问题描述

我开始在美容院管理系统上工作,到目前为止一切似乎都运行良好,但在管理面板中,我创建了一个动画导航侧边栏,每次关闭页面时,我都会收到“无法删除 TCL 命令”。对此有何想法?此外,任何关于代码的提示和意见都将受到高度赞赏。

完全错误:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\USER\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1885, in __call__
    return self.func(*args)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 2306, in destroy
    Misc.destroy(self)
  File "C:\Users\USER\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 632, in destroy
    self.tk.deletecommand(name)
_tkinter.TclError: can't delete Tcl command

代码:

from tkinter import *

import setuptools.command.alias
from PIL import Image, ImageTk

class AdminPage:
    def __init__(self):

        # Creating main window
        self.adminPageWindow = Tk()
        self.adminPageWindow.bind("<Escape>", self.minimizeScreen)
        self.adminPageWindow.bind("<F11>", self.maximizeScreen)
        self.adminPageWindow.attributes("-fullscreen", True)
        self.adminPageWindow.config( bg="#FFFFFF")

        # Creating Nav Bar
        # Creating default Vars
        self.min_w = 50  # Minimum width of the frame
        self.max_w = 135  # Maximum width of the frame
        self.cur_width = self.min_w  # Increasing width of the frame
        self.expanded = False  # Check if it is completely expanded

        # Creating the Images from existing files
        self.logoImage = ImageTk.PhotoImage (Image.open ('Resources/Images/Logo.png').resize ((30, 30), Image.ANTIALIAS))
        self.dashboard_img = ImageTk.PhotoImage (Image.open ('Resources/Images/Dashboard_img.png').resize ((40, 40), Image.ANTIALIAS))
        self.new_img = ImageTk.PhotoImage (Image.open ('Resources/Images/New_img.png').resize ((40, 40), Image.ANTIALIAS))
        self.stock_img = ImageTk.PhotoImage (Image.open ('Resources/Images/stock_img.png').resize ((40, 40), Image.ANTIALIAS))
        self.pay_img = ImageTk.PhotoImage (Image.open ('Resources/Images/pay_img.png').resize ((40, 40), Image.ANTIALIAS))
        self.profile_img = ImageTk.PhotoImage (Image.open ('Resources/Images/profile_img.png').resize ((40, 40), Image.ANTIALIAS))

        self.adminPageWindow.update ()

        self.navbar = Frame (self.adminPageWindow, width=50, height=self.adminPageWindow.winfo_height (), bg="#FEF17D")
        self.navbar.pack(side=LEFT)

        # Creating Corresponding
        self.dashboard_button = Button(self.navbar,image=self.dashboard_img,bg='#FEF17D',relief='flat', command=self.dashboardPage)
        self.new_button = Button(self.navbar, image=self.new_img, bg="#FEF17D", relief='flat')
        self.stock_button = Button(self.navbar, image=self.stock_img, bg="#FEF17D", relief='flat')
        self.pay_button = Button(self.navbar, image=self.pay_img, bg="#FEF17D", relief='flat')
        self.profile_button = Button(self.navbar, image=self.profile_img, bg="#FEF17D", relief='flat')

        self.emptyLabel = Label(self.navbar, image=self.logoImage, bg="#FEF17D").grid(row=0, column=0, pady=5, padx=5)
        self.dashboard_button.grid(row=1, column=0, pady=40)
        self.new_button.grid(row=2, column=0, pady=40)
        self.stock_button.grid(row=3, column=0, pady=40)
        self.pay_button.grid(row=4, column=0, pady=40)
        self.profile_button.grid(row=5, column=0, pady=40)

        self.navbar.bind('<Enter>', lambda e: self.expand())
        self.navbar.bind('<Leave>', lambda e: self.contract())
        self.navbar.grid_propagate(False)

        self.headerFrame = Frame(self.adminPageWindow, bg="#FEF17D", height=50)
        self.headerFrame.pack(fill=X)

        self.mainFrame = Frame (self.adminPageWindow, bg="#FFFFFF", width=self.adminPageWindow.winfo_width () - 50 ,height=self.adminPageWindow.winfo_height () - 150)
        self.mainFrame.pack()
        self.footerFrame = Frame(self.adminPageWindow, bg="#FFFFFF", width=self.adminPageWindow.winfo_width()-50, height=50)
        self.footerFrame.pack(fill=X, side=BOTTOM)

        self.headerFrameLabel = Label(self.headerFrame, text="Admin Panel", font=("Courier New Italic Bold", 18), bg="#FEF17D")
        self.headerFrameLabel.pack(anchor=CENTER, pady=5)
        text = "Salon Management System V1.00\nCreated by Nael Ghannam"
        self.footerFrameLabel = Label(self.footerFrame, text=text, font=("Courier New Italic", 10), bg="#FFFFFF")
        self.footerFrameLabel.pack()




        self.adminPageWindow.mainloop()

    def minimizeScreen(self, event):
        self.adminPageWindow.attributes ('-fullscreen', False)
        window_Width = 1280
        window_height = 720

        screenWidth = self.adminPageWindow.winfo_screenwidth ()
        screen_Height = self.adminPageWindow.winfo_screenheight ()

        position_top = int (screen_Height / 2 - window_height / 2)
        position_right = int (screenWidth / 2 - window_Width / 2)

        self.adminPageWindow.geometry (f"{window_Width}x{window_height}+{position_right}+{position_top}")
        return None
    def maximizeScreen(self, event):
        self.adminPageWindow.attributes ('-fullscreen', True)
        return None
    def expand(self):
        self.cur_width += 10  # Increase the width by 10
        rep = self.adminPageWindow.after (5, self.expand)  # Repeat this func every 5 ms
        self.navbar.config (width=self.cur_width)  # Change the width to new increase width
        if self.cur_width >= self.max_w:  # If width is greater than maximum width
            self.expanded = True  # Frame is expended
            self.adminPageWindow.after_cancel (rep)  # Stop repeating the func
            self.fill()
    def contract(self):
        self.cur_width -= 10  # Reduce the width by 10
        rep = self.adminPageWindow.after (5, self.contract)  # Call this func every 5 ms
        self.navbar.config (width=self.cur_width)  # Change the width to new reduced width
        if self.cur_width <= self.min_w:  # If it is back to normal width
            self.expanded = False  # Frame is not expanded
            self.navbar.after_cancel (rep)  # Stop repeating the func
            self.fill()
    def fill(self):
        if self.expanded:  # If the frame is exanded
            # Show a text, and remove the image
            self.dashboard_button.config (text='Dashboard', image='', font=("Courier New Italic", 14))
            self.new_button.config (text='New Entries', image='', font=("Courier New Italic", 14))
            self.stock_button.config (text='Stock', image='', font=("Courier New Italic", 14))
            self.pay_button.config (text='Pay', image='', font=("Courier New Italic", 14))
            self.profile_button.config (text='Profiles', image='', font=("Courier New Italic", 14))
        else:
            # Bring the image back
            self.dashboard_button.config (image=self.dashboard_img, font=(0, 21))
            self.new_button.config (image=self.new_img, font=(0, 21))
            self.stock_button.config (image=self.stock_img, font=(0, 21))
            self.pay_button.config (image=self.pay_img, font=(0, 21))
            self.profile_button.config (image=self.profile_img, font=(0, 21))

    def dashboardPage(self):
        self.headerFrameLabel.config(text="Dashboard")


AdminPage()

标签: tkinter

解决方案


尝试将您expand和您的contract功能更改为:

def expand(self):
    self.cur_width += 10  # Increase the width by 10
    self.navbar.config(width=self.cur_width)  # Change the width to new increase width
    if self.cur_width >= self.max_w:  # If width is greater than maximum width
        self.expanded = True  # Frame is expended
        self.fill()
    else:
        rep = self.adminPageWindow.after(5, self.expand)  # Repeat this func every 5 ms

def contract(self):
    self.cur_width -= 10  # Reduce the width by 10
    self.navbar.config(width=self.cur_width)  # Change the width to new reduced width
    if self.cur_width <= self.min_w:  # If it is back to normal width
        self.expanded = False  # Frame is not expanded
        self.fill()
    else:
        rep = self.adminPageWindow.after(5, self.contract)  # Call this func every 5 ms

您会注意到我移动了代码,因此您无需调用after_cancel. 我认为问题在于after_cancel取消.after脚本但tkinter不会将其从内存中删除,因此当您关闭窗口时它会再次尝试将其删除。据我所知,这可能是tkinter.


推荐阅读