【问题标题】:TypeError when user cancels input dialog用户取消输入对话框时出现类型错误
【发布时间】:2015-12-12 22:04:43
【问题描述】:

我创建了一个程序,用户可以在其中任意一个键“H”、“E”、“L”、“O”、“W”、“R”、“D”,乌龟会画出对应的乌龟图形窗口中的字母。首先询问用户是否要从默认值更改字母尺寸,然后根据他们的回答,他们将被询问新的字母高度/宽度,或者被询问输入颜色名称。然后,在程序运行时,用户还可以按 F1 - F10 中的任意键来更改字母颜色,从 1-0 (0 = 10) 中的任意数字来更改每个字母的粗细,甚至从他们在按“k”时出现的对话框中更改他们在开始时设置的字母尺寸。而且,在对话框中输入值的用户正是我在哪里有一个问题!但首先,这是我的程序的代码:

""" A simple typing program

Press "H" to draw an H
Press "E" to draw an E
Press "L" to draw a L
Press "O" to draw an O
Press "W" to draw a W
Press "R" to draw a R
Press "D" to draw a D
Press "ENTER" to go to the next line
Press "TAB" to make an indent
Press "BACKSPACE" to go backwards an indent
Press the "Up" or "Down" arrow keys to move the turtle up or down the canvas
Press "SPACE" to clear the canvas of your drawings
Press "ESC" to exit the program
Press any number from 1-0 on the key board (1 = 1, 0 = 10) to set the letter thickness
Press any key from F1-F10 to set a random color of the letter
(F1-F8 = colors, F9 = Custom Color, F10 = Original color)

That is all you need to know! Enjoy! """

from turtle import *
from tkinter import *
import math
from tkinter.colorchooser import *
import copy

# Function variables

space_width = 30 # Default value: 30
letter_height = 100 # Default value: 100
letter_width = 50 # Default value: 50



change = (input("Would you like to change the size of the letters from the defult value? y/any other input: "))

y = ("yes")
n = ("no")


if change in y:
    try:
        while True:
            try:
                letter_height = int(input("Enter a value from 1-170 to set the height of each letter in pixels: "))
                break
            except ValueError:
                print("That is not an integer! Please enter an integer from 1-170!")
        while letter_height > 170:
            try:
                letter_height = int(input("That value is too much. Please reenter a value from 1-170: "))
                while letter_height < 1:
                    letter_height = int(input("That value is too little. Please reenter a value from 1-170: "))
            except ValueError:
                print("That is not an integer! Please enter an integer from 1-170!")
        while letter_height < 1:
            try:
                letter_height = int(input("That value is too little. Please reenter a value from 1-170: "))
                while letter_height > 170:
                    letter_height = int(input("That value is too much. Please reenter a value from 1-170: "))
            except ValueError:
                print("That is not an integer! Please enter an integer from 1-170!")
        while True:
            try:
                letter_width = int(input("Enter a value from 1-170 to set the width of each letter in pixels: "))
                break
            except ValueError:
                print("That is not an integer! Please enter an integer from 1-170!")
        while letter_width > 170:
            try:
                letter_width = int(input("That value is too much. Please reenter a value from 1-170: "))
                while letter_width < 1:
                    letter_width = int(input("That value is too little. Please reenter a value from 1-170: "))
            except ValueError:
                print("That is not an integer! Please enter an integer from 1-170!")
        while letter_width < 1:
            try:
                letter_width = int(input("That value is too little. Please reenter a value from 1-170: "))
                while letter_width > 170:
                    letter_width = int(input("That value is too much. Please reenter a value from 1-170: "))
            except ValueError:
                print("That is not an integer! Please enter an integer from 1-170!")
            break
    except:
        input("That is not an answer! Please enter either y or n!: ")

elif change in n:
    space_width = 30 # Default value: 30
    letter_height = 100 # Default value: 100
    letter_width = 50 # Default value: 50

#The 'while' loop below will tell the user to choose a color name, but if the color is invalid, an exception is thrown, and the user must reenter a color name until a valid color name is entered. 

while True:
    try:
        pen_color=input("Enter a color name to set the pen color: ")
        pencolor(pen_color)
        break
    except:
        print("That is either not an available color or not a valid color name. Please reenter the name of another color or a valid one.")

def NewLetterDimensions():
    global letter_height
    letter_height = (numinput("New Letter Height", "Please set the new letter height: ", minval = 10, maxval = 170))

    global letter_width
    letter_width = (numinput("New Letter Width", "Please set the new letter width: ", minval = 10, maxval = 170))

    penup()
    goto(xcor(), ycor() +letter_height)
    pendown()
    listen()

def draw_space():
    # Add a space 30 pixels wide.
    penup()
    forward(space_width)
    pendown()

def move_turtle():
    # Pick up the turtle and move it to its starting location.
    penup()
    goto(-200, 100)
    pendown()

def draw_H():
    # Draw the left leg of H.
    # The turtle starts at the bottom left of the letter, pointing right.
    left(90)
    forward(letter_height)
    # Draw the bar of the H.
    # The turtle starts at the top of the left leg, pointing up.
    forward(-letter_height/2)
    right(90)
    forward(letter_width)
    # Draw the right leg of the H.
    # The turtle starts at the right side of the bar, pointing right.
    left(90)
    forward(letter_height/2)
    forward(-letter_height)
    right(90)
    # The H is drawn.
    # The turtle is in the top right, pointing right.
    draw_space()


def draw_E():
    # Draw an E.
    left(90)
    forward(letter_height)
    right(90)
    forward(letter_width)
    forward(-letter_width)
    right(90)
    forward(letter_height/2)
    left(90)
    forward(letter_width)
    forward(-letter_width)
    right(90)
    forward(letter_height/2)
    left(90)
    forward(letter_width)
    draw_space()

def draw_L():
    # Draw an L
    left(90)
    forward(letter_height)
    forward(-letter_height)
    right(90)
    forward(letter_width)
    draw_space()

def draw_O():
    # Draw an O
    forward(letter_width)
    left(90)
    forward(letter_height)
    left(90)
    forward(letter_width)
    left(90)
    forward(letter_height)
    left(90)
    forward(letter_width)
    draw_space()

def draw_newline():
    # This funtion will pick up the turtle and move it to a second line below HELLO
    penup()
    goto(xcor(), ycor() -letter_height-5)
    pendown()

def draw_W():
    # This function will draw a W
    left(105)
    forward(letter_height)
    backward(letter_height)
    right(40)
    forward(letter_height/2)
    right(131)
    forward(letter_height/2)
    left(141)
    forward(letter_height)
    right(165)
    penup()
    forward(letter_height)
    left(90)
    draw_space()

def draw_second_O():
    # This function will draw the O in "world"
    forward(letter_width)
    right(90)
    forward(letter_height)
    right(90)
    forward(letter_width)
    right(90)
    forward(letter_height)
    right(90)
    penup()
    forward(letter_width)
    right(90)
    forward(letter_height)
    left(90)
    draw_space()

def draw_R(letter_width, letter_height):
    # This function will draw an R

    slant_height = (math.sqrt(letter_width**2 + (letter_height/2)**2))
    slant_angle = (90+(90-(math.degrees(math.acos(letter_width/slant_height)))))
    space_angle = (180 - slant_angle)

    left(90)
    forward(letter_height)
    right(90)
    forward(letter_width)
    right(90)
    forward(letter_height/2)
    right(90)
    forward(letter_width)
    left(slant_angle)
    forward(slant_height)
    left(space_angle)
    draw_space()

def draw_D(letter_width, letter_height):
    # This function will draw a REAL D

    angle_height = math.sqrt(letter_width**2 + (letter_height/2)**2)
    D_angle = (90+(math.degrees(math.acos(letter_width/angle_height))))
    Second_D_angle = ((90 - (D_angle-90)) + (90-(math.degrees(math.acos(letter_width/angle_height)))))
    D_space_angle = (math.degrees(math.atan(letter_width/(letter_height/2))))

    left(90)
    forward(letter_height)
    right(D_angle)
    forward(angle_height)
    right(Second_D_angle)
    forward(angle_height)
    left(90+D_space_angle)
    penup()
    forward(letter_width)
    draw_space()

def skip(x, y):
    penup()
    goto(x, y)
    pendown()

def back():
    penup()
    bk(letter_width + space_width)
    pendown()

def walk():
    penup()
    forward(letter_width + space_width)
    pendown()

def soar():
    penup()
    left(90)
    forward(letter_height + 5)
    right(90)
    pendown()

def fall():
    penup()
    right(90)
    forward(letter_height + 5)
    left(90)
    pendown()

setup(1.0, 1.0)

def RotateRight():
    right(90)

def RotateLeft():
    left(90)

def Up():
    penup()
    goto(xcor(),ycor()+(letter_height+5))
    pendown()

def width1():
    width(1)

def width2():
    width(2)

def width3():
    width(3)

def width4():
    width(4)

def width5():
    width(5)

def width6():
    width(6)

def width7():
    width(7)

def width8():
    width(8)

def width9():
    width(9)

def width10():
    width(10)

def Blue():
    color("blue")

def Red():
    color("red")

def DarkGreen():
    color("dark green")

def Purple():
    color("purple")

def Pink():
    color("pink")

def Brown():
    color("brown")

def Orange():
    color("orange")

def Black():
    color("Black")

def OriginalColor():
    color(pen_color)

def getColor():
    Color = askcolor()
    color_name = Color[1]
    colormode(255)
    color(color_name)

move_turtle()
speed(0)
color(pen_color)
listen()
##onkey(Color, "F10")
onkey(NewLetterDimensions, "k")
onkey(width1, "1")
onkey(width2, "2")
onkey(width3, "3")
onkey(width4, "4")
onkey(width5, "5")
onkey(width6, "6")
onkey(width7, "7")
onkey(width8, "8")
onkey(width9, "9")
onkey(width10, "0")
onkey(Blue, "F1")
onkey(Red, "F2")
onkey(DarkGreen, "F3")
onkey(Purple, "F4")
onkey(Pink, "F5")
onkey(Brown, "F6")
onkey(Orange, "F7")
onkey(Black, "F8")
onkey(getColor, "F9")
onkey(OriginalColor, "F10")
onscreenclick(goto)
onscreenclick(skip)
onkey(clear, "space")
onkey(back, "BackSpace")
onkey(walk, "Tab")
onkey(Up, "Up")
onkey(draw_H, "h")
onkey(bye, "Escape")
onkey(draw_E, "e")
onkey(draw_L, "l")
onkey(draw_O, "o")
onkey(draw_W, "w")
onkey(lambda: draw_R(letter_width, letter_height), "r")
onkey(lambda: draw_D(letter_width, letter_height), "d")
onkey(draw_newline, "Return")

这是我遇到问题的地方:

def NewLetterDimensions():
    global letter_height
    letter_height = (numinput("New Letter Height", "Please set the new letter height: ", minval = 10, maxval = 170))

    global letter_width
    letter_width = (numinput("New Letter Width", "Please set the new letter width: ", minval = 10, maxval = 170))

    penup()
    goto(xcor(), ycor() +letter_height)
    pendown()
    listen()

问题是,当对话框出现时,用户选择“取消”而不是输入值,我得到这个错误:

    Exception in Tkinter callback
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/idlelib/run.py", line 119, in main
    seq, request = rpc.request_queue.get(block=True, timeout=0.05)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/queue.py", line 172, in get
    raise Empty
queue.Empty

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/tkinter/__init__.py", line 1549, in __call__
    return self.func(*args)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/turtle.py", line 686, in eventfun
    fun()
  File "/Users/Rohan/Google Drive/K12 High School Documents/Computer_Science/section_5/assignment_5a.py", line 111, in NewLetterDimensions
    goto(xcor(), ycor() +letter_height)
TypeError: unsupported operand type(s) for +: 'float' and 'NoneType

用户按下回车键当然不会返回任何内容,但显然,由于某种原因,这不能用于操作。好吧,我怎样才能做到这一点,如果用户取消对话框,程序可以从之前设置的高度/宽度继续,这样就不会出现错误?非常感谢有关此问题的任何帮助! :)

【问题讨论】:

    标签: python function python-3.x input turtle-graphics


    【解决方案1】:

    如您所见,错误出现在第 117 行,在 NewLetterDimensions() 函数中,因为您尝试将 NoneType 添加到 float

    你可以检查letter_height是否为None;如果是,则返回相同的尺寸,否则更新它们。

    另外,原来的width函数已经接受了一个参数size,而不是定义函数width1()width12(),所以你可以像这样绑定按钮:

    for number in range(0, 11):
        onkey(width(number), str(number % 10))
    

    【讨论】:

    • 我试过这样的“if”语句:if letter_height == None: return letter_height else: letter_height 和这个if letter_width == None: return letter_width else: letter_width 现在,每当我输入“k”并按取消时,错误不再出现,但是当我尝试键入任何绘制字母的键,没有任何反应!
    • @R.Kap:我认为这是因为你使用了penup(),而letter_height is Nonependown() 放入了块中。
    • 实际上,我只是自己解决了这个问题,取出else 语句,然后将listen() 放在“if”语句的末尾!但是,我也试图返回用户以前拥有的值,但我找不到这样做的方法。 return 显然只是阻止它执行,那么,我还能如何让“if”语句返回高度和宽度的旧值?
    • 您可以在函数的开头保存它们,如果遇到None 情况,则恢复旧值而不是什么都不做。 :)
    • 我尝试过,但我得到了这个错误:SyntaxWarning: name 'letter_height' is used prior to global declaration。除了将旧值分配给新变量之外,我还能如何保存它?因为,这正是我所做的。
    猜你喜欢
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多