Python Turtle Graphics:如果 Tracer 关闭,OnKey 不会触发

问题描述 投票:0回答:1

我希望仅在触发

screen.update()
时才绘制屏幕,但我想立即对按键做出反应。

当我设置

screen.tracer(0)
并手动调用
screen.update()
时,仅当按键
screen.onkey()
恰好发生在更新时才会被评估,即用户需要保持按住该键足够长的时间,直到下一个
screen.update() 
会触发键盘输入进行注册,在这种情况下,这对于可用性来说是不可接受的。

如果我省略了

screen.tracer(0)
,则按键可以正确注册,但屏幕刷新会闪烁。

python turtle-graphics python-turtle
1个回答
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()
© www.soinside.com 2019 - 2024. All rights reserved.