I’m trying to implement the undo function for my image editing program. Below is part of my code:
def displayim(root, panel, img, editmenu):
global image, L
L.append(img)
print(len(L))
if (len(L) > 1):
editmenu.entryconfig(0, state=NORMAL)
else:
editmenu.entryconfig(0, state=DISABLED)
image1 = ImageTk.PhotoImage(img)
root.geometry("%dx%d+%d+%d" % (img.size[0], img.size[1], 200, 200))
panel.configure(image = image1)
panel.pack(side='top', fill='both', expand='yes')
panel.image = image1
image = img
def undo(root, panel, editmenu):
global L
i = len(L)
del L[i-1]
last = L.pop
displayim(root, panel, last, editmenu)
My idea is that when any function for opening image or adding effect to image is called, it will display the result by calling displayim. The parameter editmenu makes sure that if there is nothing to undo, the undo command will be disabled. Variable L is a list used to store the states of image after each function is called. When the undo function is invoked, it would remove the last item in the list and also the one before the last item (now became the last), and pass this new last item to displayim so that the program can display the previous state of the image and add it to the list again.
However, when I try to use the undo function, I got the error:
Exception in Tkinter callback
Traceback (most recent call last):
File "D:\Python32\lib\tkinter\__init__.py", line 1399, in __call__
return self.func(*args)
File "D:\Users\ichigo\workspace\SS2\test\main.py", line 26, in <lambda>
editmenu.add_command(label="Undo", command=lambda:file.undo(root, panel, editmenu), state=DISABLED)
File "D:\Users\ichigo\workspace\SS2\test\file.py", line 51, in undo
displayim(root, panel, last, editmenu)
File "D:\Users\ichigo\workspace\SS2\test\file.py", line 39, in displayim
image1 = ImageTk.PhotoImage(img)
File "D:\Python32\lib\site-packages\PIL\ImageTk.py", line 110, in __init__
mode = Image.getmodebase(mode)
File "D:\Python32\lib\site-packages\PIL\Image.py", line 225, in getmodebase
return ImageMode.getmode(mode).basemode
File "D:\Python32\lib\site-packages\PIL\ImageMode.py", line 50, in getmode
return _modes[mode]
TypeError: unhashable type: 'list'
Exception AttributeError: "'PhotoImage' object has no attribute '_PhotoImage__photo'" in <bound method PhotoImage.__del__ of <PIL.ImageTk.PhotoImage object at 0x01B1AA50>> ignored
I guess the error means the variable last I passed to displayim from undo isn’t a PIL image object so it can’t be added to PhotoImage. Is there any solution available for me now? Please tell me if you have any suggestions.
You should change
last = L.poptolast = L.pop()L.popreturn a<build-in method pop of list object>but not aPIL image object