I'm creating a homework planner program using Tkinter, and I've run into a problem when trying to add an error label to the screen to show the user that they might have entered a duplicate assignment. Here's the constructor for the label (entFrame is where I put the user entries):
duplicateLabel = Label(entFrame, text="Warning: the entered assignment is a duplicate!", bg=bgColor, font=regularFont)
When a user submits an assignment, a function runs that creates a new assignment object. In that function, I call a method of the assignment to check if it is a duplicate. In that method, I create a list of all the lines of a csv file where I store the assignments. Then, I check the new assignment's attributes to some of the stored attributes of previous assignments. If the conditional is true, I add the warning label to the screen. Otherwise, I try to destroy the label to remove it from the screen to get rid of a previous warning from an old assignment.
def checkDuplicates(self):
contents = []
file = open("homeworkAssets/assignmentsFile", "r")
for content in csv.reader(file):
contents.append(content)
file.close()
for assignment in contents:
if self.course == assignment[1] and self.dueDate == assignment[2] and self.details == assignment[3]:
duplicateLabel.grid(row=0, column=0, columnspan=2)
else:
duplicateLabel.destroy()
My first thought was that the .destroy() method was deleting the Label object, although when I added a print statement after that last line, the console read: .!labelframe.!labelframe.!label6
which I assume means it hasn't been deleted. When I run the program with an empty csv file and I add one assignment, and then a duplicate assignment, I receive this error message (sorry for the bad formatting, I couldn't figure out how to do it properly):
File "/Users/max/Desktop/Coding/Python/Misc./homeworkPlannerRevised.py", line 212, in checkDuplicates duplicateLabel.grid(row=0, column=0, columnspan=2) File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/__init__.py", line 2493, in grid_configure self.tk.call( _tkinter.TclError: bad window path name ".!labelframe.!labelframe.!label6"
Why is this error occurring and how do I fix it? Thanks in advance!
CodePudding user response:
.destroy()
removes widget from window (and memory) but it doesn't remove path from variable.
print(duplicateLabel)
shows path to object even if it is destroyed.
You run destroy()
in loop - so one loop can destroy label and next loop may try to destroy it again - and this can make problem.
You could assign None
to variable after destroying and check None
before destroying.
if duplicateLabel is not None:
duplicateLabel.destroy()
duplicateLabel = None
but if you destroy object then later you have to create it again
if duplicateLabel is None:
duplicateLabel = Label(...)
But frankly you don't need destroy()
but grid_forget()
to hide widget without destroying.
if self.course == assignment[1] and self.dueDate == assignment[2] and self.details == assignment[3]:
duplicateLabel.grid(row=0, column=0, columnspan=2)
else:
duplicateLabel.grid_forget()