3

I am tying to automate some stuff using python.I use pynput to listen key combinations. I am trying to listen ctrl+shift+alt s combination. I have no problem with modifier keys but only with letter keys. I have looked the python documentation page and tried followings:

from pynput import keyboard
from subprocess import Popen, PIPE
from evdev import uinput, ecodes as e
import os

# The key combination to check
COMBINATION = {keyboard.Key.shift, keyboard.Key.ctrl, keyboard.Key.alt, keyboard.KeyCode.from_char('k')}

# The currently active modifiers
current = set()

def on_press(key):
    if key in COMBINATION:
        current.add(key)
        if all(k in current for k in COMBINATION):
            print("x")
    if key == keyboard.Key.esc:
        listener.stop()

def on_release(key):
    try:
        current.remove(key)
    except KeyError:
        pass

with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
        listener.join()

After running the python file from terminal, script cannot detect my key combination.

Emre CEKEN
  • 31
  • 1
  • 2

2 Answers2

2

From the docs, you can use this method. https://pynput.readthedocs.io/en/latest/keyboard.html

from pynput import keyboard

def on_activate():
    print('Global hotkey activated!')

def for_canonical(f):
    return lambda k: f(l.canonical(k))

hotkey = keyboard.HotKey(
    keyboard.HotKey.parse('<ctrl>+<alt>+h'),
    on_activate)
with keyboard.Listener(
        on_press=for_canonical(hotkey.press),
        on_release=for_canonical(hotkey.release)) as l:
    l.join()
Sri
  • 2,281
  • 2
  • 17
  • 24
  • 1
    I already saw that, but I cannot see anything about letter keys in this code snippet. Thanks. – Emre CEKEN Apr 18 '20 at 19:57
  • That's the answer I've been searching for hours ! Thanks, that works perfectly ! :D – Quantum Sushi Jan 30 '21 at 16:30
  • To me, this feels like a lazy contribution, without really taking time to think about op's needs and code. This is just a copy-paste from the documentation, without the above, or explaining why it applies to OPs question. – Andreas Schuldei Jan 11 '22 at 11:59
  • Code is syntactically broken; line 7 `l.canonical`references `l` before assignment – Stof Aug 02 '22 at 01:53
  • `keyboard.HotKey` does not work for me, but `keyboard.GlobalHotKeys` does. – Samantra Apr 22 '23 at 22:50
0

When you press <shift> + k, the letter typed is capital 'K', which is not equal to lowercase 'k'. Note that Sri's answer passes the key through listener.canonical, which turns the capital letter into a lowercase one.

I suggest you add the following line at the start of on_press:

    key = listener.canonical(key)

Using the global listener object like this makes me uncomfortable. It will break if you split your code into modules. Unfortunately, it appears to be the intended usage.

For some reason, listener.canonical(keyboard.Key.esc) != keyboard.Key.esc. Consider moving your escape clause to precede key = listener.canonical(key) as well.

Also note that, on my platform (X window manager on Ubuntu), pynput does not correctly interpret <shift> + <alt> as just <alt>. I have to type the keys in this order: <alt> + <ctrl> + <shift> + k. I suggest not using shift + alt key combinations if you can avoid it. If you get mysterious errors with key combinations, try printing out the keys so you can see what pynput thinks they are.

Mark Peschel
  • 115
  • 3
  • 10