I have been making a game using pygame in python and it refuses to identify the 1 key.
if event.type == KEYDOWN and event.key == K_1:
print("pass")
started = True
I added the "pass" to check if something else is wrong but nothing happens. I have used a few other keys like up, down, w, s and enter which work but it won't recognize any numbers.
If it helps, I am using a Trust Xpress wireless keyboard.
In regard to Dominic's question , I have tried both number pad and standard keys.
Your problem probably has nothing to do with your keyboard.
You probably just left numb lock off and are using the keypad.
If not, get the window to print all events and see if anything comes up when you press the 1 key.
It should be 49, but if it's not, just use whatever it is.
If nothing comes up at all, and you can't use the keyboard elsewhere, then it is something wrong with your keyboard.
Related
I have been facing this problem for the last week,I thought it would be trivial but after trying many different approaches I don't know what else to try.
I have an application where I need to have key detection (to move a robot arm with the keyboard) but when I press enter I need to add some inputs, which should be as long as I want, just some normal input("insert here").
I know about the python libraries to get key detection, I got pynput to work successfully but it crashes my raspberry pi when I start and stop the threads a few times,I tried the Keyboard library but the whole root requirement is a let down, I also got curses to work and this seems to be solid and is (almost) not causing any issues, so detecting 1 key is not a problem.
I of course know how to name my files and get all the information that I need by doing input(), so if I had to use one of those options the job would be rather simple, the challenge comes when I try to apply both approaches together, basically detect the keys to do everything I need, and use python Input to get all the inputs from the user as soon as enter is pressed, all the libraries to detect key seems to take full control and they don't want to release it without a fight. They seem to expect the user to always require single key detection but in my case I would need to constantly turn it on and off, I couldn't figure out any efficient (or not) way to get it to work properly.
My question is:
What is the best approach to have key detection + full user input when needed with curses (or any alternative) in a non blocky way (as my code need to do some other things while listening for keys), is creating and destroying the whole thing the only alternative?
This is my current test code that I created for simplicity (which works but blocks everything while listening for keys):
import curses
import time
import os
stdscr = None
addInput = False
def SetupCurses():
global stdscr
stdscr = curses.initscr()
curses.cbreak()
stdscr.keypad(1)
def StartCurse():
global addInput
key = ''
while key != ord('q'):
key = stdscr.getch()
stdscr.addstr(str(key))
if key == ord('a'):
print("\nyou pressed a\n")
if key == 10:
print("\nyou pressed enter!\n")
addInput = True
break
def EndCurse():
curses.endwin()
while(True):
SetupCurses()
StartCurse()
EndCurse()
if addInput:
theinput = input("add your input\n")
print(theinput)
time.sleep(4)
addInput = False
#if there isn't any input to add I want the code to continue because there is non-related keys stuff to do, but of course it stopped at "StartCurse"
#if there is something to add the code can stop at addInput
The reason for the loop is because the user can save as many positions as he want, so after adding some inputs the possibility of adding more is there.
I saw people making this non-blocking by closing the curses loop after a few seconds (which stops everything anyway...) kind of getting the input by luck...something like:
def ExecuteCurses():
global AddInput
#open it and close it very quickly to grab a key if it is pressed
c = stdscr.getch()
if c == ord('a'):
print("you pressed a")
AddInput = True
time.sleep(1)
curses.endwin()
If you want a full and long user input you will need to use the curses.echo() and then use the stdscr.getstr(). That will wait for the user to press enter().
And to not block the program while getting input you need threading which you will have to import at the top of your program
And for the threading here is a link so you can find out more about threading.
I hope it answers your question
I am trying to write a program that captures at any time which key is being pressed. The ultimate goal is to control a robot from the keyboard, e.g. using wasd keys to control movement. It's rather easy using pygame, but as I want to be able to access my robot over SSH, I am looking for a purely bash-based solution. The curses library seems to be the way to go (but please let me know if there is a better solution). I now have something like this:
import curses
def main(screen):
screen.timeout(50)
key = ''
while key != 'q':
try:
key = screen.getkey()
screen.addstr(0, 0, 'key: {:<10}'.format(key))
except:
screen.addstr(0, 0, 'key: {:<10}'.format('N/A'))
if __name__ == '__main__':
curses.wrapper(main)
which largely works fine, except for some unexpected behaviour: when I press and hold a key, it very briefly (and only once) alternates between the key in question and the 'N/A' fallback, as if I press and release and then press and hold.
I think my issue is caused by the character repeat delay setting on my machine. Indeed, if I increase the curses timeout setting to half a second, the problem is 'solved', but I want my program to be more responsive than half a second. Any way I can overrule the character repeat delay within my program? Or alternative solutions?
Note: Not sure if this is relevant, but I am using bash on Windows 10 (WSL) for testing purposes, and would ultimately like to run it on Raspbian.
The following fails to print a hashtag?
import pyautogui
pyautogui.typewrite('#');
It prints '~'.
Pyautogui is keyboard layout dependent.
You could try switching your keyboard layout to the US keyboard layout (which is what Pyautogui is based on). For example, the French Canadian keyboard layout has a # where the ~ key normally is, which could explain why you're experiencing this behavior.
As Sean Kennedy said, it's a keyboard layout issue. They're still working on support for non-US-English keyboard layouts.
https://github.com/asweigart/pyautogui/issues/137
Luckily you have an English keyboard layout, so you'll have far fewer issues and you should be able to patch them. You can redefine whether certain keys need shift or not by editing _pyautogui_win.py:
def _keyDown(key):
if key not in keyboardMapping or keyboardMapping[key] is None: return
needsShift = pyautogui.isShiftCharacter(key)
# insert this code, exactly here:
if key == '#': needsShift = False
if key == '+': needsShift = False
if key == '<': needsShift = False
#print(key,needsShift) #####debug
# continue
Taken from:
https://github.com/asweigart/pyautogui/issues/46#issuecomment-132640299
I haven't looked at the code myself, but you might find that you're better or worse making the edit inside isShiftCharacter.
I should have kept reading. isShiftCharacter might become a rabbit hole:
By the way: Deleting #,+,< in the following function, did NOT work
(util.py in .\pyautogui):
def isShiftCharacter(character): return character.isupper() or
character in '~!##$%^&*()_+{}|:"<>?'
Maybe .isupper() regards these characters as upper? I didn't check
further
I think this can be an alternative if pyautogui doesn't work for #,etc
import keyboard
keyboard.write('#')
I know that there are already some questions posted regarding the same issue but the solutions proposed didn't help me.
I want to monitor the state of the arrow keys (pressed/not pressed) at any given time so I have the following code:
import pygame
pygame.init()
a=[0,0,0,0]
while True:
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
a[0]=1;
else:
a[0]=0;
if keys[pygame.K_RIGHT]:
a[1]=1;
else:
a[1]=0;
if keys[pygame.K_UP]:
a[2]=1;
else:
a[2]=0;
if keys[pygame.K_DOWN]:
a[3]=1;
else:
a[3]=0;
print a
pygame.event.pump()
So, basically, I keep printing a list a of 4 numbers, each representing an arrow key (1 if pressed, 0 otherwise).
However all values of the list are always zero even if i keep pressing the arrow keys for long.
I also tried printing the whole keys array : Turns out all entries are zeros again, no matter which keys I press and for how long
Any help would be greatly appreciated...
Thanks !
EDIT: Forgot to mention that I am using python 2.7 on windows 7
First off, if you haven't actually created a pygame window, no events will be passed to pygame and therefore the result of pygame.key.get_pressed() won't update. Pygame only receives events on the currrent pygame window. You're probably looking at the console, which is not receiving events. I added pygame.display.set_mode((100,100)) just after pygame.init() and then ran the program. I clicked inside the pygame window. Then the console start displaying the appropriate ones in the console.
Also suggest adding something to pause the loop like time.sleep and something like event checking to break out of it. (proper exiting)
I know that this is a vague question, but I was hoping to get some help. I know VBA pretty well, and have been able to accomplish some simple tasks in python as well as the statistical programming language in R.
What I am looking to do is create a simple application that lets me capture data, some of which is captured from the keyboard. Every time there is a keystroke, I wanted to create a new record in my dataset.
For some context, think about creating a simple interface that lets me track the location (and duration) of the puck in an NHL hockey game.
I am not really a programmer, but know just enough to get in trouble and am not really sure where to get started. I simply am looking for some thoughts on a very basic (non-commercial) solution.
Many thanks in advance.
EDIT: I want to capture how long the puck is each zone. I plan on using the directional keys left/right to "follow" the puck from zone to each. Each time the puck changes to a zone, I want to "close" the active record and start a new one. The start and end times will let me calculate how long the puck was in the zone. I also need a way to stop the creation of a new record for things like faceoffs, tv time outs, and end of period. I was planning on using the spacebar. My thought is that if I do this correctly, when I follow along, the times recorded should match up with what is posted on the game clock found on tv. Yes, this is a crazy idea.
If you choose to program in Python:
You could use the pygame package to easily capture keyboard events. The library was built to write games, but would probably give you the functionality that you are looking for with keydown/keyup events. It also handles mouse events and (since it is intended for games) has the ability to do graphics/text. The documentation is really good and it is cross platform. A possible downside is that you have to have a "screen" and it has to have focus. Here is a small example:
import pygame
def main():
"""
Pygame Example
"""
pygame.init()
screen = pygame.display.set_mode((200, 200))
app_running = True
while app_running:
# Get all key/mouse events from system.
events = pygame.event.get()
# Loop thru each event...
for e in events:
# Handle when the program is killed.
if e.type == pygame.QUIT:
app_running = False
break
# Handle key events.
elif e.type == pygame.KEYDOWN:
# Exit if escape is pressed.
if e.key == pygame.K_ESCAPE:
app_running = False
# Do something when the right arrow
# is pressed.
elif e.key == pygame.K_RIGHT:
print "right arrow pressed"
# Do something when the left arrow
# is pressed.
elif e.key == pygame.K_LEFT:
print "left arrow pressed"
# and so on ...
# Fill the screen to blank it.
#screen.fill(mycolor)
# Write someting to the screen to display.
#screen.blit(some_image, some_position)
# Flip to display.
#screen.flip()
pygame.quit()
if __name__ == '__main__':
main()
If you are using a version of Windows you could use the msvcrt library but the event handling is not as nice as pygame: instead of events, you have to deal with raw keyboard output and it is a little less intuitive. Here is a small code snippet from Robert Gillies on ActiveState:
import msvcrt
def funkeypress():
"""
Waits for the user to press any key including function keys. Returns
the ascii code for the key or the scancode for the function key.
"""
while 1:
if msvcrt.kbhit(): # Key pressed?
a = ord(msvcrt.getch()) # get first byte of keyscan code
if a == 0 or a == 224: # is it a function key?
b = ord(msvcrt.getch()) # get next byte of key scan code
x = a + (b*256) # cook it.
return x # return cooked scancode
else:
return a # else return ascii code
Look at scan() for keyboard input in R. And you didn't ask about mouse input, but consider locator() for that.
Put it a loop if you want the output immediately.
Is it necessary that you program it yourself? There is a free program called jwatcher Designed for scoring animal behavior in ethological studies. It seems like that would be well-suited to your task.