Python, check if arrow key pressed - python

How to check if user presses an arrow key in python? I want something like this:
if right_key.pressed():
do_some_shit()
elif left_key.pressed():
do_other_stuff()

In your terminal (or anacoonda prompt) run this command to install pynput library:
pip install pynput
And, in your editor
from pynput import keyboard
from pynput.keyboard import Key
def on_key_release(key):
if key == Key.right:
print("Right key clicked")
elif key == Key.left:
print("Left key clicked")
elif key == Key.up:
print("Up key clicked")
elif key == Key.down:
print("Down key clicked")
elif key == Key.esc:
exit()
with keyboard.Listener(on_release=on_key_release) as listener:
listener.join()
More info

You can use this code:
import keyboard
import time
while True:
try:
if keyboard.is_pressed('left'):
print('You Pressed left!')
time.sleep(0.1)
if keyboard.is_pressed('right'):
print('You Pressed right!')
time.sleep(0.1)
if keyboard.is_pressed('down'):
print('You Pressed down!')
time.sleep(0.1)
if keyboard.is_pressed('up'):
print('You Pressed up!')
time.sleep(0.1)
except:
break

By using listeners you will not have to play an infinite loop. Which I think is more elegant. This code will help you:
from pynput import keyboard
def on_press(key):
if key == keyboard.Key.up:
print('PRESSED')
if key == keyboard.Key.esc:
listener.stop()
with keyboard.Listener(on_press=on_press) as listener:
listener.join()
Note that with 'keyboard.Key' you can detect the key that you want. You can even reproduce the case of holding two keys at the same time and detecting a combination!

This is the code I made, but it's only for a Pygame project with a window
If you need the arrows in pygame I recommend this code:
from pygame.locals import *
import pygame
import sys
window_height = 100
window_width = 100
window = pygame.display.set_mode((window_width, window_height))
# This is the code to check if a player is pushing the arrows
while True:
for evenement in pygame.event.get():
if evenement.type == QUIT or (evenement.type == KEYDOWN and
evenement.key == K_ESCAPE):
print('QUIT')
pygame.quit()
sys.exit()
if evenement.type == KEYDOWN and evenement.key == K_RIGHT:
print("Clicked on the right arrow")
if evenement.type == KEYDOWN and evenement.key == K_LEFT:
print("Clicked on the left arrow")
if evenement.type == KEYDOWN and evenement.key == K_UP:
print("Clicked on the up arrow")
if evenement.type == KEYDOWN and evenement.key == K_DOWN:
print("Clicked on the down arrow")

Related

pynput events executing twice

def pressLetter(charIn):
val = getKeyValue(charIn)
PressKey(val)
return
def KeyboardEvents():
from pynput import keyboard
with keyboard.Events() as events:
for event in events:
if event.key == keyboard.Key.space:
pressLetter('w')
Pressing space types ww. How would I rewrite this so that it only presses w once?
Well, I figured it out. It appears that keyboard.Events() registers button press events on both key pressed and key released. Meaning that...
if event.key == keyboard.Key.space:
pressLetter('w')
Presses w twice because it executes both on key pressed, and then key released.
The solution I found was to use keyboard.Listener() instead
def pressLetter(charIn):
val = getKeyValue(charIn)
PressKey(val)
return
def on_press(key):
if key == keyboard.Key.space:
pressLetter('w')
def on_release(key):
if key == keyboard.Key.esc:
return False
with keyboard.Listener(on_press=on_press, on_release=on_release) as listener:
listener.join()
listener = keyboard.Listener(on_press=on_press, on_release=on_release)
listener.start()
This worked for me:
def KeyboardEvents():
from pynput import keyboard
with keyboard.Events() as events:
for event in events:
if isinstance(event, keyboard.Events.Press):
if event.key == keyboard.Key.space:
pressLetter('w')

Pygame, do command exactly 1 time when pressed a key then wait for another click

if key("LEFT"):
if select_x != 100:
select_x-=64
else:
print("BORDER REACHED")
If you run the Program and press the LEFT key, pygame will do the command written below forever until you stop pressing the key, I want pygame just to do the command 1 time and then waits for another click.
Do the event handling in the event loop for event in pygame.event.get()::
import pygame as pg
pg.init()
screen = pg.display.set_mode((320, 240))
clock = pg.time.Clock()
select_x = 164
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
if event.key == pg.K_LEFT:
if select_x != 100:
select_x -= 64
else:
print("BORDER REACHED")
screen.fill((30, 30, 30))
pg.display.flip()
clock.tick(30)
pg.quit()

pygame keydown combinations (ctrl + key or shift + key)

I have some python code with keydown events happening, I am basically wondering if it is possible to have two keys pressed at a time, like ctrl+a or something like that. Is this possible, or will I have to find a workaround?
Use pygame.key.get_mods() to get state of special keys like Control or Shift.
get_mods() gives one integer and you have to use bitwise operators to compare it with constants like KMOD_SHIFT
See documentation: pygame.key
EDIT: example
import pygame
import pygame.locals
pygame.init()
screen = pygame.display.set_mode((300,200))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_a and pygame.key.get_mods() & pygame.KMOD_SHIFT:
print "pressed: SHIFT + A"
pygame.quit()
BTW: you can use KMOD_LSHIFT or KMOD_RSHIFT to test only left shift or only right shift.
EDIT:
BTW: example how to use get_pressed()
you have to use K_LSHIFT and K_LSHIFT to check both shifts.
it print "pressed: SHIFT + A" again and again if you keep SHIFT+A pressed.
.
import pygame
import pygame.locals
pygame.init()
screen = pygame.display.set_mode((300,200))
running = True
while running:
#
# events
#
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
#
# others
#
all_keys = pygame.key.get_pressed()
#print 'shift:', all_keys[pygame.K_LSHIFT], all_keys[pygame.K_RSHIFT]
if all_keys[pygame.K_a] and (all_keys[pygame.K_LSHIFT] or all_keys[pygame.K_RSHIFT]):
print "pressed: SHIFT + A"
pygame.quit()
BTW: get_pressed() and get_mods() give actual information only if pygame.event.get() was use before.
EDIT:
How to recognize A, CTRL+A, SHIFT+A, ALT+A, CTRL+SHIFT+A, CTRL+ALT+A, SHIFT+ALT+A, , CTRL+SHIFT+ALT+A
import pygame
import pygame.locals
pygame.init()
screen = pygame.display.set_mode((300,200))
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_a:
mods = pygame.key.get_mods()
if mods & pygame.KMOD_CTRL and mods & pygame.KMOD_SHIFT and mods & pygame.KMOD_ALT:
print "pressed: CTRL+SHIFT+ALT + A"
elif mods & pygame.KMOD_CTRL and mods & pygame.KMOD_SHIFT:
print "pressed: CTRL+SHIFT + A"
elif mods & pygame.KMOD_CTRL and mods & pygame.KMOD_ALT:
print "pressed: CTRL+ALT + A"
elif mods & pygame.KMOD_SHIFT and mods & pygame.KMOD_ALT:
print "pressed: SHIFT+ALT + A"
elif mods & pygame.KMOD_SHIFT:
print "pressed: SHIFT + A"
elif mods & pygame.KMOD_CTRL:
print "pressed: CTRL + A"
elif mods & pygame.KMOD_ALT:
print "pressed: ALT + A"
else:
print "pressed: A"
pygame.quit()
BTW: On my computer is problem with Right Alt because it is used for native chars. It doesn't work with KMOD_ALT and KMOD_RALT.
If this is for a GUI.
from Tkinter import *
class Application(Frame):
def __init__(self, parent):
Frame.__init__(self,parent)
self.grid()
self.create_widgets()
def create_widgets(self):
widg = Text(self)
widg.grid(row=0,column=0)
self.bind_all("<Control-a>", self.check) #This checks if lower case a is pressed
self.bind_all("<Control-A>", self.check) #This checks if upper case a is pressed
def check(self, event): #Make sure to have event inside the function
print("Control-a pressed")
root = Tk()
app = Application(root)
root.mainloop()
For Pygame you should be looking for get_pressed instead of keydown, cuz keydown happens only once, key down happens until key is released.
for two keys pressed just do a if-stament.
# store the result of the get_pressed() in those variables.
if key_ctrl_is_down and key_a_is_down:
dowhatever()

pygame joystick slows down event handling

I am using a function to wait until a controller is present, but i ran into a problem. I wanted the function to stop when I press a key. Usually these events are handled just fine, but in this part it works terrible. The event seems to be added to the event queue very late or sometimes not at all. My guess is that it is because of the uninitialisation and reinitialisation of pygame.joystick. I just don't know how to solve it. I used this program to create the error:
import pygame, sys
from pygame.locals import *
pygame.init()
SCREEN = pygame.display.set_mode((500,500))
ChangeRun = False
pygame.joystick.init()
if pygame.joystick.get_count() == 0:
while pygame.joystick.get_count() == 0:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type in [KEYUP, KEYDOWN]:
if event.key == K_ESCAPE:
ChangeRun = True
if ChangeRun == True:
break
pygame.joystick.quit()
pygame.joystick.init()
pygame.quit()
sys.exit()
I wanted to use the escape key to end the program, but only after a lot of pressing it works. The same happens with the QUIT event. When printing the events I found that most of the time no event was found.
I use windows 8.1 and python 3.4 and pygame 1.9.2
I have no joystick so I can't test it but normally I would do this similar to mouse and I wouldn't wait for controller:
import pygame
from pygame.locals import *
pygame.init()
pygame.joystick.init()
screen = pygame.display.set_mode((500,500))
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
elif event.type == JOYBUTTONDOWN:
print 'joy:', event.joy, 'button:', event.button
# the end
pygame.joystick.quit()
pygame.quit()

Keys aren't doing what they're suppost to

I'm using pygame to draw a line:
import pygame
from pygame.locals import*
import sys
pygame.init()
screen = pygame.display.set_mode((600,500))
pygame.display.set_caption("Drawing Lines")
while True:
for event in pygame.event.get():
if event.type == KEYDOWN and event.key == K_DOWN:
sys.exit()
screen.fill((0,80,0))
color = 100,255,200
width = 8
pygame.draw.line(screen, color, (100,100), (500,400), width)
pygame.display.update()
for some reason, I can't get this is work:
while True:
for event in pygame.event.get():
if event.type == KEYDOWN and event.key == K_DOWN:
sys.exit()
It doesnt show any error, it just doesnt work. I want to be able to press the down key and have it quit the program but it doesnt do that. I have to quit the idle. Any help will do. thanks.
This is because KEYDOWN is just the event that a key is pressed down, not that the down key has been pushed. To fix this, you have to first check if a KEYDOWN event has happened, and if it has, check what key that was pushed.
for event in pygame.event.get():
if event.type == KEYDOWN and event.key == K_DOWN:
sys.exit()
Check out the docs on this subject to learn more.

Categories