How to detect keypress in python using keyboard module? - python

I am making a program in python to detect what key is pressed and based on my keyboard it will make a decision.
I want to implement it using keyboard module in python.
I would do something like this,
import keyboard
while True:
if keyboard.read_key() == 'enter':
print('Enter is pressed)
if keyboard.read_key() == 'q':
print('Quitting the program)
break
if keyboard.read_key() == 's':
print('Skiping the things')
But it doesn't work. When I execute this program, I have to press s twice to execute the "s" block.
Also, I have a problem that is after the execution is finished, it writes all the keys in my command prompt is it possible to fix that?

As per Keyboard documentation:
Other applications, such as some games, may register hooks that swallow all key events. In this case keyboard will be unable to report events.
One way to solve your problem with keyboard module is keyboard.wait('key')
# Blocks until you press esc
keyboard.wait('esc')
Something work around is as below:
import keyboard
keyboard.wait('enter')
print('Enter is pressed')
keyboard.wait('q')
print('Quitting the program')
keyboard.wait('s')
print('Skiping the things')

As Far I Know There is only one efficient way to Detect user input weather it keybored or mouse input Which is library called pynput ......
from pynput.keyboard import Key , Listener , Controller
keyboard = Controller()
DoubleShot=False
shot=False
def on_press(key):
global DoubleShot
global shot
if Key.num_lock == key:
print("activate")
DoubleShot=True
if DoubleShot:
if Key.shift == key:
shot = not shot
if shot:
keyboard.press(Key.shift)
keyboard.release(Key.shift)
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 create this for a game to shoot multiple time on 'shift' clicked
code activate only when ' numlock ' clicked.....
Controller is for clicking any key you want
Note:
In My case infinity looping was a problem that's why shot variable is there to stop looping

Related

I want to check if ANY key is pressed, is this possible?

How do I check if ANY key is pressed?
this is how I know to detect one key:
import keyboard # using module keyboard
while True: # making a loop
if keyboard.is_pressed('a'): # if key 'q' is pressed
print('You Pressed A Key!')
break # finishing the loop
How do I check if any key (not just letters) is pressed?
For example, if someone presses the spacebar it works, the same for numbers and function keys, etc.
while True:
# Wait for the next event.
event = keyboard.read_event()
if event.event_type == keyboard.KEY_DOWN:
print(event.name) # to check key name
Press any key and get the key name.
it can be done using the msvcrt module as the following:
import msvcrt
while True:
if msvcrt.kbhit():
key = msvcrt.getch()
break
or the keyboard, although i am not sure of how of a good practice this code is:
import keyboard
while True:
try:
print(keyboard.read_key())
break
except:
pass
if this is bad practice please informe me in the coments so i can mark it as unfavored
thankyou.
Correct solution in Windows is to use msvcrt
Please check thread here:
How to detect key presses?
I think somehow should be possible also with builtin input() command.
Have a nice day!

Keyboard module toggle Listener

I just found out about the pynput library which is exactly what I have been looking for. My goal is to capure the keys the user is typing and whenever a specific sequence of keys was captured I want the computer to write a sequence to the current carret's position. After that I want to capture the usersĀ“s keys again until another noteworthy sequence occurs. And so on.
The problem is that the simulated key strokes of keyboard.write() are also considered by the Listener which leads to an infinite loop which was funny the first time it occurred but I am trying to get rid of it now obv.
My approach is to stop the Listener and create a new one after the computer is done typing but this process slows down a lot after the first start_listener() invocation and isn't optimal in the first place I think. And I am out of further ideas so I was hoping someone could help here.
Here is my code so far:
import keyboard
from pynput.keyboard import Key, Listener
def on_press(key):
stop_listener()
keyboard.write("Hello", 0.05)
start_listener()
def on_release(key):
if key == Key.esc:
return False
def start_listener():
global listener
listener = Listener(on_press=on_press, on_release=on_release)
listener.start()
listener.join()
def stop_listener():
global listener
listener.stop()
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
There is a simple solution to the problem. I actually missed that I used two packages that have nothing to do with each other. Thanks to the ease to install them on my IDE.
Anyway my solution is now to only use the already present keyboard package https://pypi.org/project/keyboard/ and not pynput.keyboard
It turn out to be really easy when not using two separate packages :).
Here is the code:
# coding=utf8
import keyboard as k
def on_press(key = k.KeyboardEvent):
k.write(key.name, 0.0)
k.on_press(on_press)
k.wait()
On my Linux Mint I need admin privileges to run keyboard but I can do the same with pynput.keyboard.Controller and methods press(), release(), time.sleep()
Instead of stoping and starting listenere I would use global variable paused = False to control when on_press should runs code.
from pynput.keyboard import Key, Listener, Controller
import time
keyboard = Controller()
def on_press(key):
global paused # inform function to assign new value to global variable (instead of creating local variable)
if not paused:
paused = True
#keyboard.type("Hello") # module pynput.keyboard.Controller
for char in "Hello":
keyboard.press(char) # pynput.keyboard.Controller
keyboard.release(char) # pynput.keyboard.Controller
time.sleep(0.05)
paused = False
def on_release(key):
if not paused:
if key == Key.esc:
return False
# global variable with default value at start
paused = False
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
Tested on Linux Mint 20, Python 3.8.5, pynput 1.7.3

How to run multiple loops simultaneously in Python?

I'm trying to do something that seems very basic, but I keep getting myself stuck inside of loops that don't allow me to perform other actions. For example:
def functionOne():
if x key is pressed:
do something
def functionTwo():
if y key is pressed:
do something else
def functionThree():
if z key is pressed:
do something else
def main():
functionOne()
functionTwo()
functionThree()
main()
I was trying to to do while loops in each function, but that locks each function in its own loop cycle. I essentially want my program to run until I press a very specific key combination from the Python keyboard package. I assume loops are the way to keep a program running?
Or say, if I wanted to implement this on a GUI, and only exit the program when hitting the quit button on the GUI, while waiting for the other buttons to be clicked to do something else.
I'm aware that I could do a giant main loop with conditions nested inside one another, but I'm hoping there is a cleaner way to do this involving functions.
Try this way:-
def functionOne(key):
if key != 'x':
return
if x key is pressed:
do something
def functionTwo(key):
if key != 'y':
return
if y key is pressed:
do something else
def functionThree(key):
if key != 'z':
return
if z key is pressed:
do something else
def main():
while key != 'q':
key = input("Enter the key :")
functionOne(key)
functionTwo(key)
functionThree(key)
main()
Other than that you can use threading if functions are computationally heavy and key input interval is smaller than the computational time of the functions.
you could take advantage of pynput
first install it
pip install pynput
then you can achieve what you are looking for like the following example (obtained from pynput documentation):
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()

Typing Test, how to make input save when spacebar is pressed

My friend and I were building a typing test. We are using the input() function in python to get input from the user. The problem is that we have to press enter to make the input save and we want that button to be spacebar instead. Is there any way to do this or another module we could use to solve this problem?
for i in range(num_words):
print(final_sentence)
print("")
typed_word = input("Type>")
words_to_list(typed_word)
os.system('clear')
You should probably use other modules like keyboard or pynput because input() detects whole strings while those modules detect key presses. Detect key presses, print them, and stop when Key.space (in pynput case) is pressed.
Something like this:
from pynput.keyboard import Listener
from pynput.keyboard import Key
words=''
def on_press(key):
if key==Key.space:
listener.stop()
print (words)
def on_release(key):
global words
typed = str(key).replace("'", "")
words = words + typed
with Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
This code detects key press using pynput.keyboard's handy listener, and adds it to words until space is pressed. When space is pressed the script stops the listener and prints the typed sentence.

{Py3} How do I get a user to press a key and carry on the program without pressing enter after?

from time import sleep
alive = True
while alive == True:
print("You have awoken in a unknown land.")
sleep(2)
print("\nDo you go north, south, east or west?")
print("Press the up arrow to go north.")
print("Press the down arrow to go south.")
print("Press the left arrow to go west.")
print("Press the right arrow to go east.")
input(" ")
How do I get the user to press one of the arrow keys and have the program carry on without the need of pressing the enter key?
Thanks in advance!
~Lorenzo
You may look into a package like pynput for multiplatform support. Pynput implements mouse and keyboard listeners. This will also allow you to do WSAD movement in your RPG-like game.
For keyboard listeners, you can have a onpress/onrelease key. The help files will have some better examples.
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()
If you want to use up/down/left/right (arrow keys) for movement, this may be the easiest least painful solution too.
You Could Make Options Like:
option = input('1/2/3/4:')
or:
Python has a keyboard module with many features. You Can Use It In Both Shell and Console.
Install it, perhaps with this command:
pip3 install keyboard
Then use it in code like:
import keyboard #Using module keyboard
while True: #making a loop
try: #used try so that if user pressed other than the given key error will not be shown
if keyboard.is_pressed('up'): #if key 'up' is pressed.You can use right,left,up,down and others
print('You Pressed A Key!')
#your code to move up here.
break #finishing the loop
else:
pass
except:
break #if user pressed other than the given key the loop will break
You can set it to multiple Key Detection:
if keyboard.is_pressed('up') or keyboard.is_pressed('down') or keyboard.is_pressed('left') or keyboard.is_pressed('right'):
#then do this
You Can Also Do Something like:
if keyboard.is_pressed('up') and keyboard.is_pressed('down'):
#then do this
It Also Detect Key For The Whole Windows.
Thanks.

Categories

Resources