我希望仅在触发
screen.update()
时才绘制屏幕,但我想立即对按键做出反应。
当我设置
screen.tracer(0)
并手动调用 screen.update()
时,仅当按键 screen.onkey()
恰好发生在更新时才会被评估,即用户需要保持按住该键足够长的时间,直到下一个 screen.update()
会触发键盘输入进行注册,在这种情况下,这对于可用性来说是不可接受的。
如果我省略了
screen.tracer(0)
,则按键可以正确注册,但屏幕刷新会闪烁。
我使用
time.sleep()
而不是 turtle.ontimer()
,并且在 sleep()
期间不会注册关键事件。
#!/usr/bin/env python3
from turtle import Turtle, Screen
import time
def default_behaviour():
"""
Here, the key presses are registered correctly.
However, drawing the screen (not pictured here, replaced by the turtle color changing)
causes flickering.
"""
screen = Screen()
t = Turtle()
def set_color(color):
nonlocal t
print(f"color: {color}\n")
t.color(color)
screen.listen()
screen.onkey(key="1", fun=lambda: set_color("red"))
screen.onkey(key="2", fun=lambda: set_color("green"))
screen.onkey(key="3", fun=lambda: set_color("blue"))
screen.exitonclick()
def tracer_sleep():
"""
Using time.sleep(): while sleeping, onkey events are not processed.
"""
screen = Screen()
screen.tracer(0)
t = Turtle()
stop_loop = False
def stop():
nonlocal stop_loop
stop_loop = True
def set_color(color):
nonlocal t
print(f"color: {color}\n")
t.color(color)
screen.listen()
screen.onkey(key="1", fun=lambda: set_color("red"))
screen.onkey(key="2", fun=lambda: set_color("green"))
screen.onkey(key="3", fun=lambda: set_color("blue"))
screen.onkey(key="q", fun=stop)
while not stop_loop:
screen.update()
time.sleep(1.0)
def tracer_ontimer():
"""
With ontimer, the events are processed and wait for the next update to be shown.
"""
screen = Screen()
screen.tracer(0)
t = Turtle()
stop_loop = False
def stop():
nonlocal stop_loop
stop_loop = True
def set_color(color):
nonlocal t
print(f"color: {color}\n")
t.color(color)
screen.listen()
screen.onkey(key="1", fun=lambda: set_color("red"))
screen.onkey(key="2", fun=lambda: set_color("green"))
screen.onkey(key="3", fun=lambda: set_color("blue"))
screen.onkey(key="q", fun=stop)
while not stop_loop:
screen.update()
screen.ontimer(lambda: screen.update(), 100)
def main():
match int(input(
"Which behaviour to test?\n"
"(1) default behaviour\n"
"(2) tracer off with time.sleep()\n"
"(3) tracer off with screen.ontimer()\n")):
case 1:
print("default behaviour:")
default_behaviour()
case 2:
print("tracer + sleep:\n")
tracer_sleep()
case 3:
print("tracer + ontimer:\n")
tracer_ontimer()
if __name__ == "__main__":
main()