Python 乌龟等待按键
Python Turtle Wait for Keypress
我想通过让用户在每次移动之前按下一个键来逐步跟随海龟绘图。
我可以像这样要求用户输入来做到这一点:
def wait():
input('Press a key')
但这是一个糟糕的解决方案,因为焦点离开了乌龟 window。
我知道 screen.listen()
并且可以使用 screen.onkeypress()
设置事件侦听器。 - 例如 my_screen.onkeypress('wait')
但不确定如何实施。
编辑:我意识到我应该更具体一些。我正在尝试追踪 Koch 曲线的递归。到目前为止我的代码如下:
import turtle
def koch(t, order, size):
"""
Make turtle t draw a Koch fractal of 'order' and 'size'.
Leave the turtle facing the same direction.
"""
wait_for_keypress()
if order == 0: # The base case is just a straight line
t.forward(size)
else:
koch(t, order-1, size/3) # Go 1/3 of the way
t.left(60)
koch(t, order-1, size/3)
t.right(120)
koch(t, order-1, size/3)
t.left(60)
koch(t, order-1, size/3)
def wait_for_keypress():
input('Press a key') # There must be a better way
t = turtle.Turtle()
s = turtle.Screen()
s.listen()
koch(t, 3, 100)
turtle.done()
这听起来像是递归生成器的工作!我们开始分形代码 运行 但我们使用 yield
和 yield from
让它停止沿途的每一步。然后我们让屏幕点击事件在我们的生成器上执行 next()
:
from turtle import Turtle, Screen
def koch(t, order, size):
"""
Make turtle t draw a Koch fractal of 'order' and 'size'.
Leave the turtle facing the same direction.
"""
if order == 0:
t.forward(size) # The base case is just a straight line
yield
else:
yield from koch(t, order - 1, size / 3) # Go 1/3 of the way
t.left(60)
yield from koch(t, order - 1, size / 3)
t.right(120)
yield from koch(t, order - 1, size / 3)
t.left(60)
yield from koch(t, order - 1, size / 3)
def click_handler(x, y):
screen.onclick(None) # disable handler while in handler
try:
next(generator)
except StopIteration:
return
screen.onclick(click_handler)
screen = Screen()
turtle = Turtle()
generator = koch(turtle, 3, 200)
screen.onclick(click_handler)
screen.mainloop()
运行 程序。每次在 window 上单击鼠标时,您都会获得一个额外的科赫分形片段。我们还可以通过一个关键事件来完成这项工作,保持导入和 koch()
例程相同:
...
def key_handler():
screen.onkey(None, "Up") # disable handler while in handler
try:
next(generator)
except StopIteration:
return
screen.onkey(key_handler, "Up")
screen = Screen()
turtle = Turtle()
generator = koch(turtle, 3, 200)
screen.onkey(key_handler, "Up")
screen.listen()
screen.mainloop()
请注意,这会响应海龟图形中的向上箭头键按下操作 window,而不是控制台中的按键操作。
像这样更改您的函数:
def wait_for_keypress():
print("'Press a key'")
fd = sys.stdin.fileno()
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
except:
pass
注:
您必须导入 sys
、termios
和 tty
我想通过让用户在每次移动之前按下一个键来逐步跟随海龟绘图。
我可以像这样要求用户输入来做到这一点:
def wait():
input('Press a key')
但这是一个糟糕的解决方案,因为焦点离开了乌龟 window。
我知道 screen.listen()
并且可以使用 screen.onkeypress()
设置事件侦听器。 - 例如 my_screen.onkeypress('wait')
但不确定如何实施。
编辑:我意识到我应该更具体一些。我正在尝试追踪 Koch 曲线的递归。到目前为止我的代码如下:
import turtle
def koch(t, order, size):
"""
Make turtle t draw a Koch fractal of 'order' and 'size'.
Leave the turtle facing the same direction.
"""
wait_for_keypress()
if order == 0: # The base case is just a straight line
t.forward(size)
else:
koch(t, order-1, size/3) # Go 1/3 of the way
t.left(60)
koch(t, order-1, size/3)
t.right(120)
koch(t, order-1, size/3)
t.left(60)
koch(t, order-1, size/3)
def wait_for_keypress():
input('Press a key') # There must be a better way
t = turtle.Turtle()
s = turtle.Screen()
s.listen()
koch(t, 3, 100)
turtle.done()
这听起来像是递归生成器的工作!我们开始分形代码 运行 但我们使用 yield
和 yield from
让它停止沿途的每一步。然后我们让屏幕点击事件在我们的生成器上执行 next()
:
from turtle import Turtle, Screen
def koch(t, order, size):
"""
Make turtle t draw a Koch fractal of 'order' and 'size'.
Leave the turtle facing the same direction.
"""
if order == 0:
t.forward(size) # The base case is just a straight line
yield
else:
yield from koch(t, order - 1, size / 3) # Go 1/3 of the way
t.left(60)
yield from koch(t, order - 1, size / 3)
t.right(120)
yield from koch(t, order - 1, size / 3)
t.left(60)
yield from koch(t, order - 1, size / 3)
def click_handler(x, y):
screen.onclick(None) # disable handler while in handler
try:
next(generator)
except StopIteration:
return
screen.onclick(click_handler)
screen = Screen()
turtle = Turtle()
generator = koch(turtle, 3, 200)
screen.onclick(click_handler)
screen.mainloop()
运行 程序。每次在 window 上单击鼠标时,您都会获得一个额外的科赫分形片段。我们还可以通过一个关键事件来完成这项工作,保持导入和 koch()
例程相同:
...
def key_handler():
screen.onkey(None, "Up") # disable handler while in handler
try:
next(generator)
except StopIteration:
return
screen.onkey(key_handler, "Up")
screen = Screen()
turtle = Turtle()
generator = koch(turtle, 3, 200)
screen.onkey(key_handler, "Up")
screen.listen()
screen.mainloop()
请注意,这会响应海龟图形中的向上箭头键按下操作 window,而不是控制台中的按键操作。
像这样更改您的函数:
def wait_for_keypress():
print("'Press a key'")
fd = sys.stdin.fileno()
try:
tty.setraw(fd)
ch = sys.stdin.read(1)
except:
pass
注:
您必须导入 sys
、termios
和 tty