在Python中使用“undo”之后的“if”语句之前执行的“else”语句

2024-09-28 22:20:23 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了以下函数,允许用户将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函数(如下所示)的用武之地。实际上,它只是撤消了使用许多堆栈调用的最后一个函数,我将其创建为deques。如果您精通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语句,即使它不一定是真的。因此,非常感谢您在解决此问题时提供的任何帮助!:)


Tags: 文件theto函数configifisfunction
1条回答
网友
1楼 · 发布于 2024-09-28 22:20:23

发生在这里:

         j = i.getfunction()
         j()

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

j()调用移到你的大if j.__name__ == "TurtleShape":语句的else:块中,你的问题就应该消失了。你知道吗

这个简短的解释是否足够让你理解问题发生的原因?或者需要我更深入地解释一下调用j()是如何使用参数iop = None调用TurtleShape?你知道吗

相关问题 更多 >