Turtle-graphics keypress event not repeating

寵の児 提交于 2019-12-24 09:37:27

问题


The following code behaves differently in different environments.

On my Windows machine (Windows 10, Python 3.6), each keypress creates a response and then nothing happens until I press a key again.

On "Python Trinkets" (https://trinket.io/python) I don't need to repeat the keypress, as holding the key down creates repeat events.

I know that the Trinket version is a JS implementation, but does that explain the difference entirely? Would the program behave the same on Linux or OS?

More importantly, is there a way to make it work on Windows so that holding a key down creates repeat events?

# import the turtle module so we can use all the neat code it contains
import turtle

# Create a variable `tina` that is a Turtle() object. Set shape to 'turtle'
tina = turtle.Turtle()
tina.shape('turtle')

# Create a variable `screen`, a Screen() object, that will handle keyss
screen = turtle.Screen()

# Define functions for each arrow key
def go_left():
  tina.left(7)

def go_right():
  tina.right(7)

def go_forward():
  tina.forward(10)

def go_backward():
  tina.backward(10)

# Tell the program which functions go with which keys
screen.onkey(go_left, 'Left')
screen.onkey(go_right, 'Right')
screen.onkey(go_forward, 'Up')
screen.onkey(go_backward, 'Down')

# Tell the screen to listen for key presses
screen.listen()
turtle.done()

回答1:


Ok, I've found the solution.

The Trinket (JS) implementation is inaccurate.

Using this code: wn.onkey(go_up, "Up") binds the function to the key-press event in "standard" Python, which means the function is only called once.

To have it repeat while the key is held down, the following is needed:

def move(event):
    my_turtle.forward(5)

turtle.getcanvas().bind('<Up>', move)



回答2:


is there a way to make it work on Windows so that holding a key down creates repeat events?

Key repeat is an operating system function and different systems handle it differently. For example, the keys on my Apple OS X system repeat by default but I can go into System Preferences / Keyboard and change the rate and even turn it off (which I did to test the code below.)

If you don't have key repeat and want to simulate it, here's a simple example of using a turtle timer event to start a key repeating on key down and turn it off on key up:

# import the turtle module so we can use all the neat code it contains
from turtle import Turtle, Screen

KEY_REPEAT_RATE = 20  # in milliseconds

# Create a variable `tina` that is a Turtle() object. Set shape to 'turtle'
tina = Turtle('turtle')

# Create a variable `screen`, a Screen() object, that will handle keys
screen = Screen()

# Define functions for each arrow key
def go_left():
    tina.left(7)
    if repeating:
        screen.ontimer(go_left, KEY_REPEAT_RATE)

def go_right():
    tina.right(7)
    if repeating:
        screen.ontimer(go_right, KEY_REPEAT_RATE)

def go_forward():
    tina.forward(10)
    if repeating:
        screen.ontimer(go_forward, KEY_REPEAT_RATE)

def go_backward():
    tina.backward(10)
    if repeating:
        screen.ontimer(go_backward, KEY_REPEAT_RATE)

def start_repeat(func):
    global repeating

    repeating = True

    func()

def stop_repeat():
    global repeating

    repeating = False

repeating = False

# Tell the program which functions go with which keys
screen.onkeypress(lambda: start_repeat(go_left), 'Left')
screen.onkeyrelease(stop_repeat, 'Left')

screen.onkeypress(lambda: start_repeat(go_right), 'Right')
screen.onkeyrelease(stop_repeat, 'Right')

screen.onkeypress(lambda: start_repeat(go_forward), 'Up')
screen.onkeyrelease(stop_repeat, 'Up')

screen.onkeypress(lambda: start_repeat(go_backward), 'Down')
screen.onkeyrelease(stop_repeat, 'Down')

# Tell the screen to listen for key presses
screen.listen()

screen.mainloop()

However, your challenge is to figure out when you need this simulated repeat and when the system already has repeat capability -- having both active will be messy.



来源:https://stackoverflow.com/questions/44863600/turtle-graphics-keypress-event-not-repeating

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!