I have a Python module that listens for a key combination using pynput then, once it's pressed, it types a string into a text program.
It works great! Except...
In the example below, the user's key combo is set to shift + space. This makes a lot of sense and will likely be the most common chosen key command for Windows users running my program. The trouble is, while the shift key is held down it changes what pynput types. Instead of 01/20/2019, it will type )!/20/2019.
I need a way to disable the keyboard until pyautogui is finished typing the string. Thanks a lot for your help!!!
Bonus question: I can't seem to get a result when the key combination includes a ctrl key. Key.ctrl simply fails to ever trigger, whilst other keys work fine.
from pynput.keyboard import Key, Controller, Listener
import time
keyboard = Controller()
def insert(): # check line 1 of config file
keyboard.type('01/20/2019')
# 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): # I don't know what this k in current for k shit is.
current.remove(key)
insert() # run insert
if key == Key.esc:
listener.stop()
def on_release(key):
try:
current.remove(key)
except KeyError:
pass
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
``
You can use pyautogui.keyUp("shift") before you type.
def insert():
f=open('tc.txt')
line=f.readlines()
insert.timestamp=(line[0])
time.sleep(.1)
pyautogui.keyUp("shift")
pyautogui.typewrite(insert.timestamp)
Related
It just doesnt work i get an error saying
AttributeError: 'Controller' object has no attribute 'is_pressed'
Code:
from pynput.mouse import Button, Controller
from pynput.keyboard import Key, Controller
from pynput.keyboard import Controller
from pynput import mouse
from pynput import keyboard
keyboard = Controller()
while True:
if keyboard.is_pressed('u'):
keyboard.press('w')
keyboard.release('w')
Can someone help me out!
pynput has special class Listener to catch pressed keys. It runs in thread and it doesn' need while True so it doesn't block main code.
Press ESC to stop it.
from pynput.keyboard import Key, Controller, Listener
def on_press(key):
print('{} pressed'.format(key))
#print(dir(key))
try:
if key.char == 'u':
keyboard.press('w')
keyboard.release('w')
except Exception as ex:
print(ex)
def on_release(key):
print('{} release'.format(key))
if key == Key.esc:
# Stop listener
return False
# --- main ---
keyboard = Controller()
listener = Listener(on_press=on_press, on_release=on_release)
listener.start()
# ... other code ...
listener.join()
BTW:
If you want global macros/hotkeys in system and use Linux then you could use special program AutoKey for this. It is created with Python and it is has GUI to create macros/script/etc.
If you want global macros/hotkeys in system and use Windows you could rather use popular AutoHotKey
If you want to create macros/hotkeys in some GUI programs then you should use GUI functions for this.
View the documentation, here's a snippet from it below.
Global hotkeys
A common use case for keyboard monitors is reacting to global hotkeys.
Since a listener does not maintain any state, hotkeys involving
multiple keys must store this state somewhere.
pynput provides the class pynput.keyboard.HotKey for this purpose. It contains two methods to update the state, designed to be easily
interoperable with a keyboard listener: pynput.keyboard.HotKey.press
and pynput.keyboard.HotKey.release which can be directly passed as
listener callbacks.
[...]
This will create a hotkey, and then use a listener to update its
state. Once all the specified keys are pressed simultaneously,
on_activate will be invoked.
Note that keys are passed through pynput.keyboard.Listener.canonical
before being passed to the HotKey instance. This is to remove any
modifier state from the key events, and to normalise modifiers with
more than one physical button.
The method pynput.keyboard.HotKey.parse is a convenience function to
transform shortcut strings to key collections. Please see its
documentation for more information.
To register a number of global hotkeys, use the convenience class
pynput.keyboard.GlobalHotKeys:
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.
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()
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.
I want to make program so that until a key is pressed it does a specific event repeatedly and when it's released it don't do anything
I am not able to achieve the same, I used pynput and keyboard library but don't know how to get this done please help
As you mentioned you have to download pynput in order to use it.
on_press function works as you hold the any key
on_release key works when you release the key
from pynput.keyboard import Key, Listener
def on_press(key):
a=5
b=3
print(a+b)
def on_release(key):
if key == Key.esc:
return False
with Listener(on_press=on_press,on_release=on_release) as listener:
listener.join()
I'm making a python program that changes my wallpaper every hour, but i want to be able to also change the wallpaper when i press a certain button.
this is the code i've tried
while True:
key = ord(getch())
but the only bad part is that it gets stuck on that until i press something. Is there a better way to do this?
You may be able to achieve what you want by using https://pypi.python.org/pypi/pynput.
See also its docs on pythonhosted http://pythonhosted.org/pynput/, especially the section about monitoring the keyboard http://pythonhosted.org/pynput/keyboard.html#monitoring-the-keyboard.
The following is an example from the docs:
from pynput.keyboard import Key
from pynput.keyboard import Listener
def on_press(key):
print('{0} pressed'.format(
key))
def on_release(key):
print('{0} release'.format(
key))
if key == Key.esc:
# Stop listener
return False
# Collect events until released
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
It will print every key you press until you press ESC, after which it will terminate.
Note that there are some operating system specific things to consider, for example on OSX the process must run as root.
I somehow accidentally found this.
import msvcrt
if msvcrt.kbhit():
Key = ord(getch())
if Key ==96:
#Do something here
And that seems to work. I think msvcrt.kbhit() is waiting for an keypress. Key = ord(getch()) takes the keypress and if Key ==96: checks if its the right keypress
Writting a CLI program, I would like to read Ctrl+<anything> commands.
How can I listen and handle i.e.: Ctrl+R combination keys from my CLI python application?
For the moment, it is necessary only for Linux environments. An pythonic approach would be the best option, but I don't know how.
From signals, it is possible to handle well-known inputs, but not custom keystrokes.
Pynput is a package that's setup to handle mouse and keyboard input for a variety of operating systems. This Github issue demonstrates how to detect held keys. If you don't want to follow the link:
from pynput import keyboard
# The key combination to check
COMBINATION = {keyboard.Key.cmd, keyboard.Key.ctrl}
# 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('All modifiers active!')
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()