Reputation: 4564
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.
Upvotes: 0
Views: 1417
Reputation: 1931
You should change last = L.pop
to last = L.pop()
L.pop
return a <build-in method pop of list object>
but not a PIL image object
Upvotes: 4