I am tying to make a program in which I press certain hot key which will then detect a key press and tell which key I pressed but whenever I press the hotkey, program doesn't respond to any keypress even the escape key and keeps running.
import keyboard
def dostuff():
print("Mew")
key = keyboard.read_key()
print('I have detected', type(key))
keyboard.add_hotkey('a', lambda: dostuff())
keyboard.wait('esc')
Can anyone tell what's the issue?
If you dont want to use the keyboard module, you can use pynput, which does the same thing,
install pynput using pip
pip install pynput
here is the code:-
from pynput import keyboard
def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener when esc key is pressed
return False
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
Related
I have got a keyboard with a non-working windows key.
I tried to fix it with Python if I press the > key, the program will press the windows key, but it's not working.
Here's the code:
import msvcrt
import pyautogui
while True:
if msvcrt.kbhit():
key_stroke = msvcrt.getch()
if key_stroke == b'>':
pyautogui.press('super')
print(key_stroke)
Can anyone help me? Thanks
To press ">" you need to press two keys "shift" + ".", when you release the "." key you registered ">" being a keystroke. but till that time you have not released the "shift" key.
In a nutshell when you execute pyautogui.press('super') in line 7, you are already pressing the "shift" key and then sending the "super" key command.
Solution to your problem is simple, release the "shift" key before sending the pyautogui.press('super') cmd.
The below code will resolve your problem.
Please install pynput package first (pip install pynput). Documentation for pynput
Solution - 1 (Modifying your code)
import msvcrt
import pyautogui
from pynput import keyboard
kb = keyboard.Controller()
while True:
if msvcrt.kbhit():
key_stroke = msvcrt.getch()
if key_stroke == b'>':
kb.release(keyboard.Key.shift)
pyautogui.press('super')
print(key_stroke)
Solution - 2 (This will give you more control over your keyboard events)
To exit from the shell press the "Esc" key.
from pynput import keyboard
kb = keyboard.Controller()
def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(
key))
if hasattr(key, 'char') and key.char == ">":
kb.release(keyboard.Key.shift)
kb.press(keyboard.Key.cmd)
kb.release(keyboard.Key.cmd)
if key == keyboard.Key.esc:
# Stop listener
return False
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
on_press=on_press,
on_release=on_release)
listener.start()
If you want to remap keys in python, the keyboard module is what you are looking for.
Please install keyboard package first (pip install keyboard). Documentation
The remap_hotkey function does exactly what you need.
keyboard.wait blocks the execution of the code until a key is pressed.
import keyboard
keyboard.remap_hotkey("Shift+.", "windows")
while True:
keyboard.wait()
Note that "Shift+." may change depending on your keyboard layout.
import keyboard
while True:
if keyboard.is_pressed('b'):
print('a')
break
This is my code it prints a when I press b.
but I want it to keep printing a when I'm holding b how do I do this.
I use this module pynput mostly for mouse events, but it handles keyboard events too.
Here is the link: https://pypi.org/project/pynput/
This library allows you to control and monitor input devices.
Currently, mouse and keyboard input and monitoring are supported.
Instruction for keyboard midway down the page:
from pynput.keyboard import Key, Controller
keyboard = Controller()
or more appropriately use pynput.keyboard.Listener like this:
from pynput import keyboard
The code below detects multiple inputs. You would have to modify it for the a to b example given in the original question.
from pynput import keyboard
def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
# ...or, in a non-blocking fashion:
listener = keyboard.Listener(
on_press=on_press,
on_release=on_release)
listener.start()
Thank you.
How about adding a small delay after the print function to allow the program to re-evaluate if the input is still being pressed?
import keyboard
import time
while True:
if keyboard.is_pressed('b'):
print('a')
time.sleep(0.1)
when I use Chrome, pynput works very good, it tells me which key have I pressed.
But when I use some other programes, such as Taskmgr.exe, games, It failed! What should I do?
my code:
from pynput import keyboard
last_event_time=time.time()
def on_press(key):
global last_event_time
last_event_time=time.time()
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
global last_event_time
last_event_time=time.time()
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False
listener2 = keyboard.Listener(
on_press=on_press)
listener2.start()
I had this particular problem for literally a year in my own code before finding the reason. If a program is launched as elevated, then a non elevated program such as your script cannot read the keyboard.
If it's important that you get it working, I knocked up some basic code a while ago to relaunch my script with admin rights. The file is here, and its run a bit like this:
if __name__ == '__main__':
console.elevate(visible=not start_minimised)
# Do your main code here
I made a minimal pynput program that does different actions when the left and right arrow keys are pressed. I want to turn this into a function that can take different values as arguments.
Here is a minimal working example without a function, and without arguments:
from pynput.keyboard import Key, Listener
def on_press(key):
print('{0} pressed'.format(key))
if key == Key.esc:
return False
with Listener(on_press=on_press) as listener:
listener.join()
It prints the key you press, and quits when you press esc.
And here is what I am trying to implement. Note that it doesn't work. Just look at the logic. When left arrow is pressed, I want the program to execute a command that depends on a given argument. And vice versa for the right arrow.
from pynput.keyboard import Key, Listener
def on_press(key, left, right):
if key == Key.left:
print("{}'s key was pressed.".format(left))
if key == Key.right:
print("{}'s key was pressed.".format(right))
if key == Key.esc:
return False
def activate(name1, name2):
with Listener(
on_press=on_press(key, left=name1, right=name2)) as listener:
listener.join()
# when pressed, the program should print what on_press() is given as argument
activate('Mark', 'John')
A bit late but I had a similar case recently.
You can use:
def activate(name1, name2):
with Listener(on_press=lambda event: on_press(event, left=name1, right=name2)) as listener:
listener.join()
I am currently looking for a library that is able to detect/monitor the keyboard.
My intention is to detect when a key is being held down and while it occurs something should happen.
Most SO posts suggest to use pygame, but i find it a bit too much, to involve a library such as that for this simple task. i've also tried with pynput, which resulted only detecting one press rather than a stream of presses.
any suggestions on how i can make this while loop detect a key is being pressed / held down...
My attempt with while loop:
from pynput import keyboard
def on_press(key):
while key == keyboard.Key.cmd_l:
try:
print('- Started recording -'.format(key))
except IOError:
print "Error"
else:
print('incorrect character {0}, press cmd_l'.format(key))
def on_release(key):
print('{0} released'.format(key))
if key == keyboard.Key.cmd_l:
print('{0} stop'.format(key))
keyboard.Listener.stop
return False
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
The while solution make it stuck in the while loop, making it impossible to get out of it.
One of the simplest way I found is to use pynput module.can be found here with nice examples as well
from pynput import keyboard
def on_press(key):
try:
print('alphanumeric key {0} pressed'.format(
key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
print('{0} released'.format(
key))
if key == keyboard.Key.esc:
# Stop listener
return False
Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
above is the example worked out for me and to install, go
sudo pip install pynput (pip3 if python3.*)
it's actually really simple. just a few lines of code, and its done!
from turtle import *
def a():
print("key is pressed!")
forward(5)
def b():
print("key is not pressed!")
backward(30)
listen()
onkeypress(a," ")
onkeyrelease(b," ")
you can replace " " with any key of your choice, surrounded in ""
examples: "a","h","e","Up","y"