Kev
Kev

Reputation: 587

Python keyboard library arrow keys problem

I was writing a script, which takes a screenshot and decodes specific key presses in the name of the image as seen below. My problem is that when I press the left keyboard arrow, also the number 4 is pressed. I can't find anything on google or in the documentation of the keyboard library. I am using Windows and Python 3.6.5

(75,)
left arrow pressed
(5, 75)
4 pressed

The same thing happens with the down arrow, but with the number 3.

(80,)
down arrow pressed
(3, 80)
2 pressed

Code:

from PIL import ImageGrab
import keyboard  # using module keyboard
import time

keys = [
    "down arrow",
    "up arrow",
    "left arrow",
    "right arrow",
    "w",
    "s",
    "a",
    "d",
    "1",
    "2",
    "3",
    "4",
    "q",
    

"e", "f" ]

if __name__ == "__main__":
    while True:
        code = []
        try:
            for key in keys:
                if keyboard.is_pressed(key):
                    print(keyboard.key_to_scan_codes(key))
                    print(f"{key} pressed")
                    code.append(1)
                else:
                    code.append(0)
                    
            if keyboard.is_pressed('esc'):
                print(key + " pressed")
                break
                
            c = "".join(map(str, code))
            snapshot = ImageGrab.grab()
            save_path = str(int(time.time()*1000)) + "-" + c + ".jpg"
            snapshot.save("tmp\\" + save_path)

        except:
            break

Upvotes: 6

Views: 38789

Answers (3)

Cristian
Cristian

Reputation: 53

Beware, language may play a role! In my case the 'up' arrow was translated to my local language, you can run the following code to get the key value for your computer:

import keyboard    
def onkeypress(event):
    print(event.name)

keyboard.on_press(onkeypress)

#Use ctrl+c to stop
while True:
    pass

Upvotes: 2

255.tar.xz
255.tar.xz

Reputation: 792

The keyboard module has simple solutions for instances like these, they use event-triggered activation rather than polling as is used in your attempt.

example code:

import keyboard

def handleLeftKey(e):
    if keyboard.is_pressed("4"):
        print("left arrow was pressed w/ key 4")
        # work your magic

keyboard.on_press_key("left", handleLeftKey)
# self-explanitory: when the left key is pressed down then do something

keyboard.on_release_key("left", handleLeftKey02)
# also self-explanitory: when the left key is released then do something

# don't use both ...on_release & ...on_press or it will be
# triggered twice per key-use (1 up, 1 down)

Replace the code below and change it to suit your needs.

if __name__ == "__main__":
    while True:
        code = []
        try:
            for key in keys:
                if keyboard.is_pressed(key):
                    print(keyboard.key_to_scan_codes(key))
                    print(f"{key} pressed")
                    code.append(1)
                else:
                    code.append(0)

Another, more dynamic approach would look like:

import keyboard

keys = [
    "down",
    "up",
    "left",
    "right",
    "w",
    "s",
    "a",
    "d",
    "1",
    "2",
    "3",
    "4",
    "q",
    "e",
    "f"
]

def kbdCallback(e):
    found = False
    for key in keys:
        if key == keyboard.normalize_name(e.name):
            print(f"{key} was pressed")
            found = True
            # work your magic

    if found == True:
        if e.name == "left":
            if keyboard.is_pressed("4"):
                print("4 & left arrow were pressed together!")
                # work your magic

keyboard.on_press(kbdCallback)
# same as keyboard.on_press_key, but it does this for EVERY key

Another issue I noticed was that you were using "left arrow" when really it was recognized as "left" (at least on my system, it may be different on yours, but I assume you want it to work on all systems so it'd be safer using "left" instead)

The last method you could use is very statically typed and has no dynamic capabilities, but would work in the case of "4+left" or "left+4"

import keyboard

def left4trigger:
    print("the keys were pressed")

keyboard.add_hotkey("4+left", left4trigger)
# works as 4+left or left+4 (all of the examples do)

You seem smart enough to figure out the rest from there.

Upvotes: 4

Hiadore
Hiadore

Reputation: 714

You may need to deactivate the NumLock button first. I have some issue on pressing Shift key when NumLock is active.

Upvotes: 0

Related Questions