2

我有一个绘制科赫雪花的 python 脚本。一切正常,除非我在绘图完成之前关闭 tutle 图形窗口,我得到一个很长的错误,这是最后一行:tkinter.tclerror: invalid command name ".38006576"。我认为这就像在 java.swing:exit_on_close 中一样。这不是默认设置。但是我还没有为 python turtle 找到类似的东西。有什么建议可以避免这种情况吗?

            import turtle
            import sys
            import easygui as eg

            def isNum(s):
                try:
                    int(s)
                    return True
                except ValueError:
                    return False

            run = True
            while run:

                msg         = "Input"
                title       = "Koch snowflake"
                fieldNames  = ["Length","Depth"]
                fieldValues = []  # we start with blanks for the values
                fieldValues = eg.multenterbox(msg,title, fieldNames)

                a=0
                iterations=0
            # make sure that none of the fields was left blank
                while 1:  # do forever, until we find acceptable values and break out
                    if fieldValues == None: 
                        break
                    errmsg = ""

                    # look for errors in the returned values
                    for i in range(len(fieldNames)):
                        if fieldValues[i].strip() == "":
                            errmsg = errmsg + ('"%s" must be filled.\n\n' % fieldNames[i])
                        elif not (isNum(fieldValues[i].strip())):
                            errmsg = errmsg + ('"%s"  requires a number.\n\n' % fieldNames[i])

                    if (isNum(fieldValues[1])):
                        if float(fieldValues[1].strip()) > 13:
                            errmsg = errmsg + ('Depth cannot be more than 13!') 

                    if errmsg == "": 
                        break # no problems found
                    else:
                        # show the box again, with the errmsg as the message    
                        fieldValues = eg.multenterbox(errmsg, title, fieldNames, fieldValues)

                #a=float(input("Length: "))
                if not fieldValues == None:
                    if isNum(fieldValues[0]) and isNum(fieldValues[1]):
                        a=float(fieldValues[0])
                        iterations=int(fieldValues[1])
                else:
                    sys.exit(0)

            #turtle settings
                turtle.bgcolor("black")
                turtle.reset()
                turtle.up() 
                turtle.setpos(-a*1.5 ,a)
                turtle.down()
                turtle.delay(0)
                turtle.speed(0)
                turtle.pencolor("white")

                koch_flake = "EJEJE"

                for i in range(iterations):
                    koch_flake = koch_flake.replace("E","EBEJEBE\n")

                turtle.down()

                for move in koch_flake:
                    if move == "E":
                        turtle.forward(a / (3 ** (iterations - 1)))
                    elif move == "B":
                        turtle.left(60)
                    elif move == "J":
                        turtle.right(120)
                turtle.hideturtle()
                image   = "KochSnowflake.gif"
                msg = "Run it again?"
                title = "Please Confirm"
                if eg.ynbox(msg, title,('Yes', 'No'),image):     # show a Continue/Cancel dialog
                    run = True
                else:  # user chose Cancel
                    sys.exit(0)
4

1 回答 1

1

Canvas在可以访问 Tkinter 根的对象上绘制海龟。捕获WM_DELETE_WINDOW根的事件。当事件被捕获时,delturtle 对象使其无法继续尝试绘制。控制海龟事件的线程将抛出 NameError,因为海龟已被删除。捕获 NameError 异常并忽略它。

这是执行此操作的代码。我测试了它;它有效并且没有抛出任何错误:

import turtle
import Tkinter
import sys
import easygui as eg

def isNum(s):
    try:
        int(s)
        return True
    except ValueError:
        return False

run = True
while run:

    msg         = "Input"
    title       = "Koch snowflake"
    fieldNames  = ["Length","Depth"]
    fieldValues = []  # we start with blanks for the values
    fieldValues = eg.multenterbox(msg,title, fieldNames)

    a=0
    iterations=0
# make sure that none of the fields was left blank
    while 1:  # do forever, until we find acceptable values and break out
        if fieldValues == None: 
            break
        errmsg = ""

        # look for errors in the returned values
        for i in range(len(fieldNames)):
            if fieldValues[i].strip() == "":
                errmsg = errmsg + ('"%s" must be filled.\n\n' % fieldNames[i])
            elif not (isNum(fieldValues[i].strip())):
                errmsg = errmsg + ('"%s"  requires a number.\n\n' % fieldNames[i])

        if (isNum(fieldValues[1])):
            if float(fieldValues[1].strip()) > 13:
                errmsg = errmsg + ('Depth cannot be more than 13!') 

        if errmsg == "": 
            break # no problems found
        else:
            # show the box again, with the errmsg as the message    
            fieldValues = eg.multenterbox(errmsg, title, fieldNames, fieldValues)

    #a=float(input("Length: "))
    if not fieldValues == None:
        if isNum(fieldValues[0]) and isNum(fieldValues[1]):
            a=float(fieldValues[0])
            iterations=int(fieldValues[1])
    else:
        sys.exit(0)

    root = Tkinter.Tk()
    cv = turtle.Canvas(root, width=200, height=200)
    cv.pack()
    screen = turtle.TurtleScreen(cv)
    screen.bgcolor("black")
    myturtle = turtle.RawTurtle(screen)

    def lastAction():
        global myturtle
        del myturtle
        root.destroy()
    root.protocol('WM_DELETE_WINDOW', lastAction)

    try:
#turtle settings
        screen.bgcolor("black")
        myturtle.reset()
        myturtle.up() 
        myturtle.setpos(-a*1.5 ,a)
        myturtle.down()
        turtle.delay(0)
        myturtle.speed(0)
        myturtle.pencolor("white")

        koch_flake = "EJEJE"

        for i in range(iterations):
            koch_flake = koch_flake.replace("E","EBEJEBE\n")

        myturtle.down()

        for move in koch_flake:
            if move == "E":
                myturtle.forward(a / (3 ** (iterations - 1)))
            elif move == "B":
                myturtle.left(60)
            elif move == "J":
                myturtle.right(120)
        myturtle.hideturtle()
    except NameError:
        pass

    image   = "KochSnowflake.gif"
    msg = "Run it again?"
    title = "Please Confirm"
    if eg.ynbox(msg, title,('Yes', 'No'),image):     # show a Continue/Cancel dialog
        run = True
    else:  # user chose Cancel
        sys.exit(0)
于 2013-04-06T07:49:54.863 回答