Your thing of using keyboard.press('w') works, but it just doesn't show as it would when you hold a key. You can test this with some kind of game that uses "w" as a movement key, then running your script and you should move forwards for the said amount of time.

Answer from Anonymous_person 3205 on Stack Overflow
๐ŸŒ
Nitratine
nitratine.net โ€บ blog โ€บ post โ€บ simulate-keypresses-in-python
Simulate Keypresses In Python - Nitratine
December 16, 2017 - Using keyboard.press we can press keys and with keyboard.release we can release a key. This allows us to type a key by pressing and releasing. You can only supply this method with one key at a time.
Top answer
1 of 2
1

Your thing of using keyboard.press('w') works, but it just doesn't show as it would when you hold a key. You can test this with some kind of game that uses "w" as a movement key, then running your script and you should move forwards for the said amount of time.

2 of 2
1

I think that the keyboard module is not as good of a choice to hold the key down as @Alderven mentioned, but it is great for detecting key presses instead if that helps your code. I would recommend using pyautogui. For example:

import pyautogui
import time

def accelerate():
    pyautogui.keyDown('w') #holds the key down
    time.sleep(5) #could be replaced with detecting an input
    pyautogui.keyUp('w') #releases the key
    return 0

Note: When you run the program, in the shell, there will not be a bunch of w's being typed as you'd expect, like this: wwwwwwwwwwwwwwwwwww. Instead, at least for me, only one w was pressed. I don't know why this occurs, although I can tell you that the key w is being pressed and this is NOT an error. I know this because I tried playing a game that involved pressing the key w (just an online web browser racing game), and the code worked. If you truly wanted the output "wwwwwwwwwwwwwwwwwwwwwwwwwww", then you can just use pyautogui's write() function:

pyautogui.write("wwwwwwwwwwwwwwwwwwwwwwwwwwwwww")

and there you go. Since you were referring to a racing game that doesn't involve getting a string of w's, this probably doesn't apply to your code.

If you want to wait for a certain input instead of holding down the key for a certain amount of time like I did, you could instead replace this:

time.sleep(5)

with this:

while True:
    if keyboard.is_pressed('del')
    break 

You would have to import the keyboard module for that to work, since pyautogui cannot detect key presses.

Pynput is another great choice of module besides pyautogui, and there are a lot of other great Stack Overflow posts about pyautogui and pynput, so if this solution doesn't work, you should check those out if you haven't already. It would also help if you clarified about the context of the code, as mentioned by @OysterShucker. If it is a racing game AI, why does it need the user to input the del key so the AI knows when to release the w key, and why not automate it? Those are questions that I would recommend answering.

Discussions

keypress - Key Presses in Python - Stack Overflow
It "presses and holds down a hotkey", see: github.com/boppreh/keyboard#keyboardpresshotkey 2021-11-27T16:13:32.383Z+00:00 ... This works, but does not answer the question, so I will vote it up but I can't accept it as the answer. 2008-09-25T23:37:49.263Z+00:00 ... If you're platform is Windows, I wouldn't actually recommend Python... More on stackoverflow.com
๐ŸŒ stackoverflow.com
python - Win32api: Press and Hold key - Stack Overflow
because that way it will just press once, wait your hold time, and then release...it won't keep pressing while sleeping 2018-03-14T15:23:02.763Z+00:00 More on stackoverflow.com
๐ŸŒ stackoverflow.com
How to make a script that will hold down a key for x seconds
I am very new to python, I have been coding in Lua for about 3 years but just the past couple of days I have been learning python, anyways I am trying to make a script that will hold down the โ€œe key on my keyboard for x seconds. We can say 2 seconds for now. More on discuss.python.org
๐ŸŒ discuss.python.org
0
0
December 12, 2022
python - How to hold keys down with pynput? - Stack Overflow
I'm using pynput and I would like to be able to hold keys down, specifically wasd but when I try and run this code it only presses the key and doesn't hold it for 2 seconds. If anyone knows what I'm doing wrong let me know. Thanks ยท import time keyboard = Controller() time.sleep(2) ... More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
PyAutoGUI
pyautogui.readthedocs.io โ€บ en โ€บ latest โ€บ keyboard.html
Keyboard Control Functions โ€” PyAutoGUI documentation
>>> pyautogui.keyDown('shift') # hold down the shift key >>> pyautogui.press('left') # press the left arrow key >>> pyautogui.press('left') # press the left arrow key >>> pyautogui.press('left') # press the left arrow key >>> pyautogui.keyUp('shift') # release the shift key ยท To make pressing hotkeys or keyboard shortcuts convenient, the hotkey() can be passed several key strings which will be pressed down in order, and then released in reverse order.
๐ŸŒ
PyPI
pypi.org โ€บ project โ€บ keyboard
keyboard ยท PyPI
Take full control of your keyboard with this small Python library. Hook global events, register hotkeys, simulate key presses and much more.
      ยป pip install keyboard
    
Published ย  Mar 23, 2020
Version ย  0.13.5
๐ŸŒ
DaniWeb
daniweb.com โ€บ programming โ€บ software-development โ€บ threads โ€บ 70746 โ€บ keypress-event-with-holding-down-the-key
python - KeyPress event with holding down the key | DaniWeb
February 22, 2007 - This way, the initial press sets up the action, but subsequent holding causes the action to continue. Basically, your function acts like two functions in one. It has one action on first keypress and a different action on key-holding.
Find elsewhere
๐ŸŒ
Python.org
discuss.python.org โ€บ python help
How to make a script that will hold down a key for x seconds - Python Help - Discussions on Python.org
December 12, 2022 - I am very new to python, I have been coding in Lua for about 3 years but just the past couple of days I have been learning python, anyways I am trying to make a script that will hold down the โ€œeโ€ key on my keyboard for xโ€ฆ
๐ŸŒ
Stack Abuse
stackabuse.com โ€บ guide-to-pythons-keyboard-module
Guide to Python's keyboard Module
October 24, 2023 - keyboard.press(key) - presses a key and holds until the release(key) function is called.
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ is there anyway to press and hold 2 key at the same time
r/learnpython on Reddit: Is there anyway to press and hold 2 key at the SAME time
October 3, 2022 -

I want pyautogui.keyDown at the same time with 'a' and 'k' and release them together I tried this but understandably there is super small delay between each keyDown

pyautogui.keyDown('a')

pyautogui.keyDown('k')

I tried pyautogui.hotkey but it will instantly press nad release those keys I cant use it as I want to keep keys pressed for a certain period of time.

๐ŸŒ
Reddit
reddit.com โ€บ r/learnprogramming โ€บ [python] simulating a held down key event
r/learnprogramming on Reddit: [Python] Simulating a held down key event
March 10, 2016 -

I am trying to write a Python program to hold down a key event to control a game. I tried this code:

import win32api
import win32con
import time   

keys = {
    "left" = win32con.VK_LEFT  
    "right" = win32con.VK_RIGHT
    "up" = win32con.VK_UP
    "down" = win32con.VK_DOWN
}

def press_key(key, delay=0.1):
    if key in keys:
        win32api.keybd_event(keys[key], 0, win32con.KEYEVENTF_EXTENDEDKEY, 0)
        time.sleep(delay)
        win32api.keybd_event(keys[key], 0, win32con.KEYEVENTF_KEYUP, 0)
    else:
        print("KEY NOT AVAILABLE")

press_key("left", 5)

If I understand correctly, this is supposed to hold the key for delay time and then stop. However, this only registers one press, waits the delay, and then ends. Did I misinterpret what KEYEVENTF_EXTENDEDKEY meant or is there another reason this code only half-works? I tried searching on StackOverflow, but all the solutions given didn't work for me.

Edit: Things I've tried: Replacing KEYEVENTF_EXTENDEDKEY with 0, got the same result.

Edit: WORKING CODE:

def press_key(key, delay=0):
    if key in keys:
        win32api.keybd_event(keys[key], 0, 0, 0)
        stop = time.time() + delay
        while time.time() < stop:
            time.sleep(0.01)
            win32api.keybd_event(keys[key], 0, 0, 0)
        win32api.keybd_event(keys[key], 0, win32con.KEYEVENTF_KEYUP, 0)
        time.sleep(0.1)
     else:
         print("KEY NOT AVAILABLE")
๐ŸŒ
GitHub
github.com โ€บ gauthsvenkat โ€บ pyKey
GitHub - gauthsvenkat/pyKey: A python library to simulate keyboard presses ยท GitHub
pressKey() will press a key and holds it until explicitly called the releaseKey function.
Starred by 56 users
Forked by 6 users
Languages ย  Python
๐ŸŒ
Read the Docs
pynput.readthedocs.io โ€บ en โ€บ latest โ€บ keyboard.html
Handling the keyboard โ€” pynput 1.7.6 documentation
A possible workaround is to just dispatch incoming messages to a queue, and let a separate thread handle them. If a callback handler raises an exception, the listener will be stopped. Since callbacks run in a dedicated thread, the exceptions will not automatically be reraised. To be notified about callback errors, call Thread.join on the listener instance: from pynput import keyboard class MyException(Exception): pass def on_press(key): if key == keyboard.Key.esc: raise MyException(key) # Collect events until released with keyboard.Listener( on_press=on_press) as listener: try: listener.join() except MyException as e: print('{0} was pressed'.format(e.args[0]))
๐ŸŒ
pytz
pythonhosted.org โ€บ pynput โ€บ keyboard.html
Handling the keyboard โ€” pynput 1.1.2 documentation
The package pynput.keyboard contains classes for controlling and monitoring the keyboard. ... from pynput.keyboard import Key, Controller keyboard = Controller() # Press and release space keyboard.press(Key.space) keyboard.release(Key.space) # Type a lower case A; this will work even if no key on the # physical keyboard is labelled 'A' keyboard.press('a') keyboard.release('a') # Type two upper case As keyboard.press('A') keyboard.release('A') with keyboard.pressed(Key.shift): keyboard.press('a') keyboard.release('a') # Type 'Hello World' using the shortcut type method keyboard.type('Hello World')
๐ŸŒ
MX Linux Forum
forum.mxlinux.org โ€บ viewtopic.php
[partially solved] I need a python script to hold a key down - MX Linux Forum
January 30, 2019 - So you have to keep pressing the (w) key up and down to more forward. a s d same. I have installed some linux drivers in the past for my Razer keyboards and mice. I don't know they would with gaming. If you own Logitech stuff... Back to the real topic: Not sure if any this will help ? https://nitratine.net/blog/post/how-to- ... in-python/ = How to Make Hotkeys in Python https://appdb.winehq.org/objectManager.
๐ŸŒ
Reddit
reddit.com โ€บ r/pythonhelp โ€บ holding a key down like on a real keyboard
r/pythonhelp on Reddit: Holding a key down like on a real keyboard
June 7, 2023 -

Hello, I'm very new to coding and I want to make my program hold down a key like a person would on a keyboard.

I'm currently using pynput like

   keyboard.press(button)   time.sleep(random.uniform(3, 5))   keyboard.release(button)

But it doesn't hold the key down. It's just one key press. And if I simulate it by using a loop, it still behave different then holding a key on a real keyboard.

Because holding a key on a real keyboard outputs one letter, then a small delay and then it starts printing the letters fast.

Anyone knows the soluion?

Top answer
1 of 2
1

System sends to programs information about pressed key ("events") only when key changes state from not-pressed to pressed or from pressed to not-pressed (released). It doesn't send events when you hold down key.

You have to use onkeypressed() to set arrow_up_pressed = True and onkeyreleased() to reset arrow_up_pressed = False and ontimer() to run repeatedly code which checks if arrow_up_pressed is True and move object up. The same you should do with arrow_down_pressed, etc.

Or you can use variable speed instead of arrow_up_pressed and arrow_down_pressed so you can assing +15 or -15 to the same variable (or 0 when keys are released). And again you need ontimer to run repeatedly code which add speed to position.

In example I use second method.


Minimal working code

import turtle

def paddle_a_up():
    global a_speed_y

    a_speed_y = +15

def paddle_a_down():
    global a_speed_y
    
    a_speed_y = -15

def paddle_a_left():
    global a_speed_x

    a_speed_x = -15

def paddle_a_right():
    global a_speed_x
    
    a_speed_x = +15

def paddle_a_stop_y():
    global a_speed_y

    a_speed_y = 0

def paddle_a_stop_x():
    global a_speed_x

    a_speed_x = 0

def update_frame():
    x, y = paddle_a.position()
    
    y += a_speed_y
    x += a_speed_x

    paddle_a.goto(x, y)

    # here update position for other objects - ie. move ball

    # run again after 50ms
    wn.ontimer(update_frame, 50)  # 50ms means ~20 FPS (Frames Per Second) (1000/50 = 20)

# --- main ---

# default values at start
a_speed_x = 0
a_speed_y = 0

wn = turtle.Screen()
paddle_a = turtle.Turtle()

# run first time after 50ms
wn.ontimer(update_frame, 50)  # 50ms means ~20 FPS (Frames Per Second) (1000ms / 50ms = 20)

# binds
wn.onkeypress(paddle_a_up, "Up")
wn.onkeypress(paddle_a_down, "Down")
wn.onkeypress(paddle_a_left, "Left")
wn.onkeypress(paddle_a_right, "Right")

wn.onkeyrelease(paddle_a_stop_y, "Up")
wn.onkeyrelease(paddle_a_stop_y, "Down")
wn.onkeyrelease(paddle_a_stop_x, "Left")
wn.onkeyrelease(paddle_a_stop_x, "Right")

wn.listen()
wn.mainloop()

BTW: The same way you would have to do this in PyGame or Pyglet.


You get better result if you add/substract value to speed instead of assigning - because when you press left and right at the same time then it will stop move (because speed +15 and -15 will gives 0), and when you release only one - ie. left - then it will again move right. In previous version when you release one but you still keep pressed other then it doesn't move again.

import turtle

def paddle_a_up_pressed():
    global a_speed_y

    a_speed_y += 15

def paddle_a_down_pressed():
    global a_speed_y
    
    a_speed_y -= 15

def paddle_a_left_pressed():
    global a_speed_x

    a_speed_x -= 15

def paddle_a_right_pressed():
    global a_speed_x
    
    a_speed_x += 15

def paddle_a_up_released():
    global a_speed_y

    a_speed_y -= 15

def paddle_a_down_released():
    global a_speed_y

    a_speed_y += 15

def paddle_a_left_released():
    global a_speed_x

    a_speed_x += 15

def paddle_a_right_released():
    global a_speed_x

    a_speed_x -= 15


def update_frame():
    x, y = paddle_a.position()
    
    x += a_speed_x
    y += a_speed_y

    paddle_a.goto(x, y)

    # run again after 50ms
    wn.ontimer(update_frame, 50)  # 50ms means ~20 FPS (Frames Per Second) (1000/50 = 20)

# --- main ---

# default values at start
a_speed_x = 0
a_speed_y = 0

wn = turtle.Screen()
paddle_a = turtle.Turtle()

# run first time after 50ms
wn.ontimer(update_frame, 50)  # 50ms means ~20 FPS (Frames Per Second) (1000/50 = 20)

# binds
wn.onkeypress(paddle_a_up_pressed, "Up")
wn.onkeypress(paddle_a_down_pressed, "Down")
wn.onkeypress(paddle_a_left_pressed, "Left")
wn.onkeypress(paddle_a_right_pressed, "Right")

wn.onkeyrelease(paddle_a_up_released, "Up")
wn.onkeyrelease(paddle_a_down_released, "Down")
wn.onkeyrelease(paddle_a_left_released, "Left")
wn.onkeyrelease(paddle_a_right_released, "Right")

wn.listen()
wn.mainloop()
2 of 2
0

The tail end of the existing answer is good, suggesting an update loop with decoupled event handlers.

But I'd go a step further. Instead of applying movement in the key handlers as done in that answer, I'd only record which keys are pressed in the handler. Then handle movement fully in the update loop based on which keys are pressed for that frame.

You can also take advantage of dicts, sets and loops to avoid repetition.

from turtle import Screen, Turtle


def update_frame():
    x, y = paddle_a.position()

    for key in keys:
        dx, dy = movements[key]
        x += dx
        y += dy

    paddle_a.goto(x, y)
    wn.ontimer(update_frame, 1000 // 30)


def bind(key):
    wn.onkeypress(lambda: keys.add(key), key)
    wn.onkeyrelease(lambda: keys.remove(key), key)


step_size = 8
movements = {
    "Up": (0, step_size), 
    "Down": (0, -step_size), 
    "Left": (-step_size, 0), 
    "Right": (step_size, 0), 
}
keys = set()
paddle_a = Turtle()
wn = Screen()

for key in movements.keys():
    bind(key)

wn.listen()
update_frame()
wn.exitonclick()

See also:

  • How to bind several key presses together in turtle graphics?
  • How do I add collision between two player controlled turtles
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ 68352489 โ€บ how-to-implement-the-pressing-and-holding-of-a-key-until-another-action-is-perfo
python - How to implement the pressing and holding of a key until another action is performed? - Stack Overflow
July 12, 2021 - I think you need to keep track of the state of things; if the current state is centered, and then you go into the "right" state, then press "d"; if the current state is "right", and you detect "right" again, then do nothing; if you're in the "right" state and leave that state, then release "d". Same goes for the "left" state. Just draw a flowchart of what you want to have happen, then you can build that logic into your program. Makes sense? ... You tried the above but the keyboard module was "not working"?