【问题标题】:A Key press event in Turtle is causing other key events to stop workingTurtle 中的按键事件导致其他按键事件停止工作
【发布时间】:2021-07-17 15:04:40
【问题描述】:

我正在尝试使用 Turtle 制作一个非常基本的 MS-Paint 版本。我有几个键和鼠标事件,但一个键事件,即 turtle.width 的 turtle.numinput(),导致我的其他键事件在我为笔宽键入所需的整数后停止工作。鼠标事件仍然有效。

turtle.numinput() 在海龟窗口打开时首先被询问,但之后其他关键事件工作正常。在我按下所需的键来更改我的笔宽之后,其他键事件停止工作。

我尝试稍微改变一下序列,甚至将代码的宽度部分复制到另一个基于 Turtle 的 python 文件中进行检查。我也遇到了同样的问题。

我不知道是什么原因造成的,非常感谢您的帮助

import turtle, random

wn = turtle.Screen()
wn.screensize(600, 600)

paint = turtle.Turtle('turtle')
colors = ['Red', 'Yellow', 'Green', 'Blue']
paint.width(turtle.numinput('width', 'Type line size (in numbers): '))
paint.speed(0)

# Arrow-Keys control function
def up():
    paint.setheading(90)
    paint.forward(100)

def down():
    paint.setheading(270)
    paint.forward(100)

def left():
    paint.setheading(180)
    paint.forward(100)

def right():
    paint.setheading(0)
    paint.forward(100)

# Color change
def colorChange():
    paint.color(random.choice(colors))

# Size change
def size():
    paint.width(turtle.numinput('width', 'Type line size (in numbers): '))

# Mouse Control (Clear + Drag) function
def clearScreen(x, y):
    paint.clear()

def dragging(x, y):
    paint.ondrag(None)
    paint.setheading(paint.towards(x, y))
    paint.goto(x, y)
    paint.ondrag(dragging)

# Shapes with random size
def square():
    for i in range(4):
        paint.forward(50)
        paint.left(90)

def circle():
    paint.circle(random.randrange(50, 100))

def rectangle():
    for i in range(2):
        paint.forward(50)
        paint.left(90)
        paint.forward(100)
        paint.left(90)

turtle.listen()

# Key-events

turtle.onkey(up, 'Up')
turtle.onkey(down, 'Down')
turtle.onkey(left, 'Left')
turtle.onkey(right, 'Right')

turtle.onkey(size, 'q')

turtle.onkey(colorChange, 'c')

# Mouse-events
turtle.onscreenclick(clearScreen, 3)
paint.ondrag(dragging)

# Shape-events
turtle.onkey(square, 's')
turtle.onkey(circle, 'o')
turtle.onkey(rectangle, 'r')

turtle.mainloop()

【问题讨论】:

    标签: python events turtle-graphics python-turtle


    【解决方案1】:

    调用numinput()(和textinput())会撤消listen() 所做的事情,因为弹出的输入窗口必须成为活动的侦听器。解决方法是在每次numinput()(和textinput())调用之后重做listen() 调用。

    以下是我通过此修复和一些样式调整对您的代码进行的返工:

    from turtle import Screen, Turtle
    from random import choice, randrange
    
    COLORS = ['Red', 'Yellow', 'Green', 'Blue']
    
    # Arrow-Keys control function
    def up():
        paint.setheading(90)
        paint.forward(100)
    
    def down():
        paint.setheading(270)
        paint.forward(100)
    
    def left():
        paint.setheading(180)
        paint.forward(100)
    
    def right():
        paint.setheading(0)
        paint.forward(100)
    
    # Color change
    def colorChange():
        paint.color(choice(COLORS))
    
    # Size change
    def size():
        paint.width(screen.numinput("width", "Type line size (in numbers):"))
        screen.listen()
    
    # Mouse Control (Clear + Drag) function
    def clearScreen(x, y):
        paint.clear()
    
    def dragging(x, y):
        paint.ondrag(None)
        paint.setheading(paint.towards(x, y))
        paint.goto(x, y)
        paint.ondrag(dragging)
    
    # Shapes with random size
    def square():
        for _ in range(4):
            paint.forward(50)
            paint.left(90)
    
    def circle():
        paint.circle(randrange(50, 100))
    
    def rectangle():
        for _ in range(2):
            paint.forward(50)
            paint.left(90)
            paint.forward(100)
            paint.left(90)
    
    screen = Screen()
    screen.screensize(600, 600)
    
    paint = Turtle('turtle')
    paint.width(screen.numinput("width", "Type line size (in numbers):"))
    paint.speed('fastest')
    
    # Key-events
    
    screen.onkey(up, 'Up')
    screen.onkey(down, 'Down')
    screen.onkey(left, 'Left')
    screen.onkey(right, 'Right')
    
    screen.onkey(size, 'q')
    screen.onkey(colorChange, 'c')
    
    # Shape-events
    screen.onkey(square, 's')
    screen.onkey(circle, 'o')
    screen.onkey(rectangle, 'r')
    
    screen.listen()
    
    # Mouse-events
    screen.onclick(clearScreen, 3)
    paint.ondrag(dragging)
    
    screen.mainloop()
    

    【讨论】:

    • 是的,这行得通!谢谢!不过有两个问题。虽然关键事件在问题期间不起作用,但鼠标事件是。这是否意味着鼠标事件不需要listen()?此外,尽管在这种情况下监听低于事件,但事件工作得很好。这是否意味着 Turtle 在监听事件方面的顺序不是很严格?
    • @Learning101,listen() 方法仅适用于键盘事件,不适用于鼠标事件。 listen() 是在事件声明之前还是之后并不重要——我通常在定义所有关键事件之前不会打开监听。否则,有些人会先于其他人变得活跃。
    【解决方案2】:

    您可能想用普通的input() 替换turtle.numinput(),它从终端而不是从实际模块获取输入,这允许所有关键操作正常进行

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      相关资源
      最近更新 更多