Is there any way to identify two keyboards separately? - python

I've used the keyboard module in python to identify a keypress event as shown below.
import keyboard
while True:
if keyboard.read_key() == "k":
print("You pressed k")
break
Now I have 2 keyboards and I want to identify the keyboard used to press the key (Something like below).
import keyboard
while True:
if 'k' of keyboard 1 pressed:
print("You pressed k of keyboard 1")
break
if 'k' of keyboard 2 is pressed:
print("You pressed k of keyboard 2")
break
Can I do this with the keyboard module? If not is there any other way to do this in python?

Related

How to pause a pynput event listener

I am trying to make a program that will read the user's inputs and if it detects a certain key combination, it will type a special character. Currently I am testing and I want the script to just output a '+' after each character that the user types. I am using the pynput event listener to determine if a key was pressed and using a 'Pause' variable so that the output of the '+' doesn't cause the event listener to make an infinite loop. The problem is that the event listener is going into an infinite loop anyway and I am not sure why.
Current typed output after each key press: +++++++++++++++++++...
Desired typed output after each key press: +
Current console output after each key press:
pause is False
getting pressed
getting released
['f']
paused
send outputs
unpaused
pause is False
getting pressed
getting released
['+']
paused
send outputs
unpaused
pause is False
getting pressed
getting released
['+']
paused
send outputs
unpaused
pause is False
getting pressed
getting released
...
Desired console output after each key press:
pause is False
getting pressed
getting released
['f']
paused
send outputs
pause is True
unpaused
import pynput
import time
from pynput.keyboard import Key, Listener, Controller
keyboardOut = Controller()
PressedKeys = []
ReleasedKeys = []
Pause = False
def on_press(key):
global PressedKeys, ReleasedKeys, Pause
print("pause is "+str(Pause))
if Pause == False:
print("getting pressed")
PressedKeys.append(key)
else:
return
def on_release(key):
global PressedKeys, ReleasedKeys, Pause
if Pause == False and len(PressedKeys) > 0:
print("getting released")
ReleasedKeys.append(key)
test_frame()
else:
return
def test_frame():
global Pause
print(PressedKeys)
Pause = True
print("paused")
print("send outputs")
keyboardOut.press('+')
keyboardOut.release('+')
PressedKeys.clear()
ReleasedKeys.clear()
Pause = False
print("unpaused")
time.sleep(1)
# Collect events until released
with Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()
How can I fix my code to *actually* pause the event listener. I am new to python, so I might just not understand how to update global variables correctly.
You have to stop the listener before using the keyboard controller.
I hope this code helps out, I tried to get as close to what I thought you were looking for.
code:
from pynput import keyboard
from time import sleep
KeyboardOut = keyboard.Controller()
pressed_keys = []
released_keys = []
def on_press(key):
try:
pressed_keys.append(format(key.char))
except AttributeError:
print('special key {0} pressed'.format(
key))
def on_release(key):
if len(pressed_keys) > 0:
released_keys.append(format(key))
test_frame()
return False
if key == keyboard.Key.esc:
# Stop listener
return False
def test_frame():
print('\n\n'+str(pressed_keys))
print('paused')
print('send outputs')
KeyboardOut.press('+')
KeyboardOut.release('+')
pressed_keys.clear()
released_keys.clear()
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.run()
print('unpaused')
sleep(1)
return True
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.run()

How to see what character is pressed with pynput python 3.7?

How can you see which button is pressed in pynput.
from pynput.keyboard import Key, Listener
def a(key):
print('{0} pressed'.format(
key))
if key == 'a':
print('ape')
with Listener(on_press = a) as listener:
listener.join()
Does not see work.
from pynput.keyboard import Listener
def a(key):
print(f"{key}, was pressed")
if key.char == "a":
print("foo")
with Listener(on_press=a) as listener:
listener.join()
Output:
q'q', was pressed
w'w', was pressed
a'a', was pressed
foo
s's', was pressed
However this will cause issues if you press the caps lock for example so I would place in a try except block:
try:
if key.char == 'a':
print("foo")
except AttributeError:
pass

how do you check if two keys are pressed consecutively in tkinter?

I am trying to create a tkinter app that checks if two keys are pressed consecutively. For example, if the user presses ":" and then the enter key right after. Is there a way to do this using key events in tkinter?
I have tried doing the following, but it does not work.
if key_pressed == ':':
if key_pressed == '<Enter>':
print("ok")
One way is to save a state for each keypress which stores the last key pressed:
from tkinter import *
root = Tk()
last_key = None
def keypress_handler(event):
global last_key
key_pressed = event.keysym
print(key_pressed)
if key_pressed == 'b':
if last_key == 'a':
print('Pressed first "a" and then "b"')
last_key = key_pressed
root.bind('<KeyPress>', keypress_handler)
root.mainloop()
If you are going to use modifiers like shift, ctrl or alt you'll have to filter them out because they also generate keypress events.

Python while key pressed function [duplicate]

I am controlling a remote toy car using python code. As of now, the code is as below:
def getkey():
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
new = termios.tcgetattr(fd)
new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
new[6][TERMIOS.VMIN] = 1
new[6][TERMIOS.VTIME] = 0
termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
c = None
try:
c = os.read(fd, 1)
finally:
termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
return c
def car():
while True:
key = getkey()
if key == 's': #Down arrow
print "Down"
Backward()
elif key == 'w': #Up arrow
print "Up"
forward()
elif key == 'a':
print "left"
Left()
elif key == 'd':
print "Right"
Right()
elif key == 'q': #Quit
print "That's It"
break
def forward():
GPIO.output(11,True) #Move forward
When I press 'w' forward() method is called and the car moves forward but wont stop until I quit the program or call GPIO.output(11, False) from some other method.
Is there any key Listener which detects the key release of any particular key?
For example, if 'w' pressed called this method and if released call some other method
Sudo code:
if w_isPressed()
forward()
else if w_isReleased()
stop()
I've seen Pygame game development library being successfully used in similar scenarios before, handling realtime systems and machinery in production, not just toy examples. I think it's a suitable candidate here too. Check out pygame.key module for what is possible to do with the keyboard input.
In short, if you are not familiar with game development, you basically continuously poll for events such as input state changes inside an 'infinite' game loop and react accordingly. Usually update the parameters of the system using deltas per time elapsed. There's plenty of tutorials on that and Pygame available around and Pygame docs are pretty solid.
A simple example of how to go about it:
import pygame
pygame.init()
# to spam the pygame.KEYDOWN event every 100ms while key being pressed
pygame.key.set_repeat(100, 100)
while 1:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_w:
print 'go forward'
if event.key == pygame.K_s:
print 'go backward'
if event.type == pygame.KEYUP:
print 'stop'
You'll need to play with pygame.KEYDOWN, pygame.KEYUP and pygame.key.set_repeat depending on how your car movement is implemented.
Faced a similar problem (I am no Python expert) but this worked for me
import pynput
from pynput import keyboard
def on_press(key):
try:
print('Key {0} pressed'.format(key.char))
#Add your code to drive motor
except AttributeError:
print('Key {0} pressed'.format(key))
#Add Code
def on_release(key):
print('{0} released'.format(key))
#Add your code to stop motor
if key == keyboard.Key.esc:
# Stop listener
# Stop the Robot Code
return False
# Collect events until released
with keyboard.Listener(
on_press=on_press,
on_release=on_release) as listener:
listener.join()

Binding key presses

I'm currently working on project where I ssh to a raspberry pi from my laptop to control some motors. I have written some code in Python that allows you to enter a letter and depending on the letter it moves forwards or backwards. However you have to press enter after every letter for the code to execute.
Is there a way that the interface detects letters without the need to press enter.
I know you can bind key presses in tkinter but I can not do that through ssh.
Thanks in advance
You could use the curses library for that.
You can grab the key that was pressed using the screen.getch() function. It will return the decimal code of the key (see ASCII Table).
An example:
import curses
screen = curses.initscr()
curses.cbreak()
screen.keypad(1)
key = ''
while key != ord('q'): # press <Q> to exit the program
key = screen.getch() # get the key
screen.addch(0, 0, key) # display it on the screen
screen.refresh()
# the same, but for <Up> and <Down> keys:
if key == curses.KEY_UP:
screen.addstr(0, 0, "Up")
elif key == curses.KEY_DOWN:
screen.addstr(0, 0, "Down")
curses.endwin()
Another option is sshkeyboard library. Simply pip install sshkeyboard, and then use the following code to detect key presses over SSH:
from sshkeyboard import listen_keyboard
def press(key):
print(f"'{key}' pressed")
def release(key):
print(f"'{key}' released")
listen_keyboard(
on_press=press,
on_release=release,
)
Inside def press you could have some logic to react to specific keys:
def press(key):
if key == "up":
print("up pressed")
elif key == "down":
print("down pressed")
elif key == "left":
print("left pressed")
elif key == "right":
print("right pressed")

Categories