我创建了以下函数,允许用户将Python海龟的形状更改为他/她从一个文件对话框中选择的图像,该对话框在按下特定按钮时弹出:
def TurtleShape(iop = None):
# "iop" is supposed to be an image path
try:
manipulateimage.config(state = NORMAL)
flipButton.config(state = NORMAL)
mirrorButton.config(state = NORMAL)
originalButton.config(state = NORMAL)
resetturtle.config(state = NORMAL)
rotateButton.config(state = NORMAL)
global klob
# The following "if-else" statement uses the "iop" argument's value as the value for "klob" if `iop` is NOT `None`
if iop != None:
klob = iop
print("lmcv")
else:
klob = filedialog.askopenfilename()
print("klobby")
global im
im = Image.open(klob)
pictures.append(im)
edited.clear()
print(im)
im.save(klob + '.gif', "GIF")
register_shape(klob + '.gif')
shape(klob + '.gif')
update()
except:
pass
上面的函数还应该使用iop
参数的值作为海龟的图像,如果它不是None
。你知道吗
现在,考虑一下这种情况;你画了一堆东西,把乌龟设置成一个图像,就在你准备给图像盖章时,你不小心按下了按钮,将乌龟重置为正常形状(是的,这个按钮存在于我的程序中)。哦,不!如果不经过所有步骤再次打开和编辑它,您将如何取回它?好吧,这就是我的undoHandler函数(如下所示)的用武之地。实际上,它只是撤消了使用许多堆栈调用的最后一个函数,我将其创建为deque
s。如果您精通Python,那么这非常简单:
def undoHandler():
if len(function) > 0 and draw.drawing == True:
undoHandler.handling = True
if not hasattr(undoHandler, "counter"):
undoHandler.counter = 0
undoHandler.counter += 1
# clear the canvas
Clear()
# Pop a point object from function deque
function.pop()
penup()
goto(-200, 100)
pendown()
try:
# Execute everything up to point before last function called
for i in function:
# Set canvas and turtle to previous state
tsd = i.recieveshape()
shape(tsd)
mndf = i.recieveheading()
setheading(mndf)
hk = i.getletterheight()
global letter_height
letter_height = hk
rk = i.getletterwidth()
global letter_width
letter_width = rk
milk = i.getspacewidth()
global space_width
space_width = milk
hw = i.getwidth()
width(hw)
op = i.getcolor()
try:
color(op)
except:
for g in colors:
cp = g.getcolor2()
colormode(255)
color(cp)
# Get function wrapped in Point object and execute it
j = i.getfunction()
j()
# Following is the code block where the issue occurs. Basically, if the function being run is equal to `TurtleShape`, then do the following...
if j.__name__ == "TurtleShape":
# `hfl` is a deque that holds all of the `pictures` deque's contents as it is cleared when the turtle is set to its default state
pictures.extend(hfl)
lmcv = pictures.pop()
pictures.append(lmcv)
try:
# Resize image to previous size if user changes it. Otherwise, skip this.
bun = picwidth.pop()
picwidth.append(bun)
mun = picheight.pop()
picheight.append(mun)
clob = lmcv.resize((int(bun), int(mun)), Image.ANTIALIAS)
except:
clob = lmcv
clob.save(klob + str(undoHandler.counter) + ".gif")
# Use the `clob.save` output from above as source image in `TurtleShape` function (this is where issue occurs)
TurtleShape(klob + str(undoHandler.counter) + ".gif")
print("Undone!")
else:
pass
except:
pass
这里发生的基本情况是,它从一个队列中获取函数(包装在Point
对象中),主函数在被调用时通过这个队列。然后函数被附加到function
文件中,之后,当用户调用undoHandler
时,屏幕被清除,最新的值从function
文件中弹出,这样除了最后一个操作之外的所有其他操作都将被再次执行。我面临的这个问题具体发生在if j.__name__ == "TurtleShape":
代码块中。基本上,由于某种原因,当用户选择撤消将海龟重置为其原始形状时,它将按其应该的方式工作,直到undoHandler执行TurtleShape
函数。出于某种原因,当undoHandler执行TurtleShape
函数时,即使我为TurtleShape
函数的iop
属性提供了有效的参数(正如您在if j.__name__ == "TurtleShape":
代码块中看到的),也会首先执行else
语句(即,文件对话框出现,而不是从if
语句继续)。只有用户在该对话框中单击cancel
,海龟才会被设置为上一个图像。
我的代码中有什么错误导致了这种情况,如何阻止这种情况的发生?我尝试过将保存在undoHandler
函数中的输出的函数中的klob
属性更改为"SaveImage"
,但是仍然没有成功。我还尝试在TurtleShape
中添加一个if-elif
语句,当它应该在iop
或一个文件对话框中选择作为klob
的值时,但仍然出现了问题。显然,它执行elif
语句,即使它不一定是真的。因此,非常感谢您在解决此问题时提供的任何帮助!:)
发生在这里:
如果您刚刚得到的函数是
TurtleShape()
函数,那么您将使用它的默认参数调用它一次(即iop = None
)。然后进入大的if j.__name__ == "TurtleShape":
语句,在if
块内再次调用它。你知道吗把
j()
调用移到你的大if j.__name__ == "TurtleShape":
语句的else:
块中,你的问题就应该消失了。你知道吗这个简短的解释是否足够让你理解问题发生的原因?或者需要我更深入地解释一下调用
j()
是如何使用参数iop = None
调用TurtleShape
?你知道吗相关问题 更多 >
编程相关推荐