我创建了以下函数,该函数允许用户将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)调用的最后一个函数。如果您精通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函数时,即使我为iop函数的TurtleShape属性提供了有效的参数(如您在if j.__name__ == "TurtleShape":代码块中所看到的),语句(即,出现文件对话框,而不是从else语句继续)。仅当用户在该对话框中单击if时,乌龟才会设置为上一个图像。

我的代码中有什么错误导致了这种情况的发生,如何阻止这种情况的发生?我试过将输出中保存在cancel函数中的函数中的klob属性更改为例如undoHandler,但还是没有运气。当应该在"SaveImage"或文件对话框中选择if-elif的值时,我也试图在TurtleShape中添加iop语句,但是仍然会出现问题。显然,即使不一定必须执行,它也会执行klob语句。因此,在解决此问题方面非常感谢您的帮助! :)

最佳答案

它发生在这里:

         j = i.getfunction()
         j()


如果您刚得到的函数是TurtleShape()函数,则使用其默认参数(即iop = None)调用一次。然后,进入大的if j.__name__ == "TurtleShape":语句,并在if块内再次调用它。

将那个j()调用移到大else:语句的if j.__name__ == "TurtleShape":块中,您的问题就会消失。

简短的解释是否足以使您理解为什么发生问题?还是您需要我更深入地说明调用j()是如何使用参数TurtleShape调用iop = None的?

关于python - 在Python中使用`undo`之后的if语句之前执行的else语句,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35033236/

10-12 16:49