Comments (29)
Hi NicoPy
I just updated the Windows key naming code to make use of virtual key codes, via a hardcoded table of their names (it's ok, it's still layout and locale independent). This should work on all languages, therefore I removed the hardcoded French words.
Could you check if the latest version still works for you?
PS: I like how github now labels me as "keyboard owner". I mean, who isn't?
from keyboard.
Certainly bug, Checking now.
from keyboard.
Tried on Python2.7, 3.3 and 3.5 on Windows 10 and couldn't reproduce. Likely some keyboard layout difference.
Could you please run this code and post the output:
import keyboard
keyboard._os_keyboard.setup_tables()
from pprint import pprint
pprint(keyboard._os_keyboard.to_scan_code)
It should print a dictionary of key names and the associated char codes.
from keyboard.
You're right, I use french keyboard.
'shift' has to be replaced by 'maj'.
Here is the output of the excerpt of code you provided :
As you can see not all keys are translated in french.
Thanks for your help.
{u'\x08': (14, True),
u'\t': (124, True),
u'\r': (28, True),
u'\x1b': (1, True),
u' ': (57, True),
u'!': (53, False),
u'"': (4, False),
u'$': (27, False),
u'%': (40, True),
u'&': (2, False),
u"'": (5, False),
u'(': (6, False),
u')': (12, False),
u'': (55, True),
u' (pave num.)': (55, False),
u'+': (78, True),
u'+ (pave num.)': (78, False),
u',': (50, False),
u'-': (74, True),
u'- (pave num.)': (74, False),
u'.': (51, True),
u'. (pave num.)': (83, False),
u'/': (52, True),
u'/ (pave num.)': (53, False),
u'0': (11, True),
u'0 (pave num.)': (82, False),
u'1': (2, True),
u'1 (pave num.)': (79, False),
u'2': (3, True),
u'2 (pave num.)': (80, False),
u'3': (4, True),
u'3 (pave num.)': (81, False),
u'4': (5, True),
u'4 (pave num.)': (75, False),
u'5': (6, True),
u'5 (pave num.)': (76, False),
u'6': (7, True),
u'6 (pave num.)': (77, False),
u'7': (8, True),
u'7 (pave num.)': (71, False),
u'8': (9, True),
u'8 (pave num.)': (72, False),
u'9': (10, True),
u'9 (pave num.)': (73, False),
u':': (52, False),
u';': (51, False),
u'<': (86, False),
u'<00>': (84, False),
u'=': (13, False),
u'>': (86, True),
u'?': (50, True),
u'A': (16, True),
u'B': (48, True),
u'C': (46, True),
u'D': (32, True),
u'E': (18, True),
u'F': (33, True),
u'G': (34, True),
u'H': (35, True),
u'I': (23, True),
u'J': (36, True),
u'K': (37, True),
u'L': (38, True),
u'M': (39, True),
u'N': (49, True),
u'O': (24, True),
u'P': (25, True),
u'Q': (30, True),
u'R': (19, True),
u'S': (31, True),
u'T': (20, True),
u'U': (22, True),
u'V': (47, True),
u'W': (44, True),
u'X': (45, True),
u'Y': (21, True),
u'Z': (17, True),
u'^': (26, False),
u'_': (9, False),
u'a': (16, False),
u'accent circonflexe': (26, False),
u'aide': (86, False),
u'alt': (56, False),
u'alt droite': (56, False),
'alt gr': 541,
u'application': (93, False),
u'attn': (70, False),
u'b': (48, False),
'backspace': (14, False),
u'bas': (80, False),
u'c': (46, False),
u'ctrl': (29, False),
u'ctrl droite': (29, False),
u'd': (32, False),
u'defil': (70, False),
u'droite': (77, False),
u'e': (18, False),
u'echap': (1, False),
u'entree': (28, False),
u'entree (pave num.)': (28, False),
'esc': (1, False),
u'espace': (57, False),
u'f': (33, False),
u'f1': (59, False),
u'f10': (68, False),
u'f11': (87, False),
u'f12': (88, False),
u'f2': (60, False),
u'f3': (61, False),
u'f4': (62, False),
u'f5': (63, False),
u'f6': (64, False),
u'f7': (65, False),
u'f8': (66, False),
u'f9': (67, False),
u'fin': (79, False),
u'g': (34, False),
u'gauche': (75, False),
u'h': (35, False),
u'haut': (72, False),
u'i': (23, False),
u'impr.ecran': (55, False),
'insert': (82, False),
u'j': (36, False),
u'k': (37, False),
u'l': (38, False),
u'm': (39, False),
u'maj': (42, False),
u'maj droite': (54, False),
u'n': (49, False),
u'o': (24, False),
u'origine': (71, False),
u'p': (25, False),
u'pause': (69, False),
u'pg.prec': (73, False),
u'pg.suiv': (81, False),
u'q': (30, False),
u'r': (19, False),
u'ret.arr': (14, False),
u's': (31, False),
'space': (57, False),
u'suppr': (83, False),
u't': (20, False),
'tab': (124, False),
u'u': (22, False),
u'v': (47, False),
u'ver.num': (69, False),
u'verr.maj': (58, False),
u'w': (44, False),
u'windows droite': (92, False),
u'windows gauche': (91, False),
u'x': (45, False),
u'y': (21, False),
u'z': (17, False),
u'\xa3': (27, True),
u'\xa7': (53, True),
u'\xa8': (26, True),
u'\xb0': (12, True),
u'\xb2': (41, False),
u'\xb5': (43, True),
u'\xe0': (11, False),
u'\xe7': (10, False),
u'\xe8': (8, False),
u'\xe9': (3, False),
u'\xf9': (40, False)}
from keyboard.
Really Windows? Translating key names?
I've pushed a hasty hack that adds french translation for a few keys and "droite/gauche". This is obviously not sustainable, I'll have to look for non-language dependent descriptions of keys. Please try the latest version and check if it works for you.
Thank you very much for submitting this bug. This is a serious problem.
from keyboard.
'shift+' is working now.
However, I think you are right, managing all languages is not the way to go.
from keyboard.
Unfortunately, only french key words are working.
PS : I agree with you. The 'owner' label is cool.
from keyboard.
Sorry, what you mean by "only french key words"? Does press('shift+a')
not work anymore? If so, could you please post your scan table again?
import keyboard
keyboard._os_keyboard.setup_tables()
from pprint import pprint
pprint(keyboard._os_keyboard.to_scan_code)
I tried erasing my table of key names and using only the virtual key codes, and it still works. Unless Windows is misreporting the virtual key codes, I don't see what could have happened.
from keyboard.
Here is the scan table :
{u'\x08': (14, True),
u'\t': (124, True),
u'\r': (28, True),
u'\x1b': (1, True),
u' ': (57, True),
u'!': (53, False),
u'"': (4, False),
u'$': (27, False),
u'%': (40, True),
u'&': (2, False),
u"'": (5, False),
u'(': (6, False),
u')': (12, False),
u'': (55, True),
u' (pave num.)': (55, False),
'+': (78, True),
u'+ (pave num.)': (78, False),
',': (50, False),
u'-': (74, True),
u'- (pave num.)': (74, False),
'.': (51, True),
u'. (pave num.)': (83, False),
u'/': (52, True),
u'/ (pave num.)': (53, False),
'0': (11, True),
u'0 (pave num.)': (82, False),
'1': (2, True),
u'1 (pave num.)': (79, False),
'2': (3, True),
u'2 (pave num.)': (80, False),
'3': (4, True),
u'3 (pave num.)': (81, False),
'4': (5, True),
u'4 (pave num.)': (75, False),
'5': (6, True),
u'5 (pave num.)': (76, False),
'6': (7, True),
u'6 (pave num.)': (77, False),
'7': (8, True),
u'7 (pave num.)': (71, False),
'8': (9, True),
u'8 (pave num.)': (72, False),
'9': (10, True),
u'9 (pave num.)': (73, False),
u':': (52, False),
u';': (51, False),
u'<': (86, False),
u'<00>': (84, False),
u'=': (13, False),
u'>': (86, True),
u'?': (50, True),
u'A': (16, True),
u'B': (48, True),
u'C': (46, True),
u'D': (32, True),
u'E': (18, True),
u'F': (33, True),
u'G': (34, True),
u'H': (35, True),
u'I': (23, True),
u'J': (36, True),
u'K': (37, True),
u'L': (38, True),
u'M': (39, True),
u'N': (49, True),
u'O': (24, True),
u'P': (25, True),
u'Q': (30, True),
u'R': (19, True),
u'S': (31, True),
u'T': (20, True),
u'U': (22, True),
u'V': (47, True),
u'W': (44, True),
u'X': (45, True),
u'Y': (21, True),
u'Z': (17, True),
u'^': (26, False),
u'_': (9, False),
'a': (16, False),
u'accent circonflexe': (26, False),
u'aide': (86, False),
'alt': (56, False),
u'alt droite': (56, False),
'alt gr': 541,
u'application': (93, False),
u'attn': (70, False),
'b': (48, False),
'backspace': (14, False),
u'bas': (80, False),
'c': (46, False),
'caps lock': (58, False),
'clear': (89, False),
'ctrl': (29, False),
u'ctrl droite': (29, False),
'd': (32, False),
u'defil': (70, False),
'delete': (83, False),
'down arrow': (80, False),
u'droite': (77, False),
'e': (18, False),
u'echap': (1, False),
'end': (79, False),
'enter': (28, False),
u'entree': (28, False),
u'entree (pave num.)': (28, False),
'erase eof': (93, False),
'esc': (1, False),
u'espace': (57, False),
'f': (33, False),
'f1': (59, False),
'f10': (68, False),
'f11': (87, False),
'f12': (88, False),
'f13': (100, False),
'f14': (101, False),
'f15': (102, False),
'f16': (103, False),
'f17': (104, False),
'f18': (105, False),
'f19': (106, False),
'f2': (60, False),
'f20': (107, False),
'f21': (108, False),
'f22': (109, False),
'f23': (110, False),
'f24': (118, False),
'f3': (61, False),
'f4': (62, False),
'f5': (63, False),
'f6': (64, False),
'f7': (65, False),
'f8': (66, False),
'f9': (67, False),
u'fin': (79, False),
'g': (34, False),
u'gauche': (75, False),
'h': (35, False),
u'haut': (72, False),
'help': (99, False),
'home': (71, False),
'i': (23, False),
u'impr.ecran': (55, False),
'insert': (82, False),
'j': (36, False),
'k': (37, False),
'l': (38, False),
'left arrow': (75, False),
'm': (39, False),
u'maj': (42, False),
u'maj droite': (54, False),
'n': (49, False),
'num lock': (69, False),
'o': (24, False),
u'origine': (71, False),
'p': (25, False),
'page down': (81, False),
'page up': (73, False),
u'pause': (69, False),
u'pg.prec': (73, False),
u'pg.suiv': (81, False),
'print screen': (84, False),
'q': (30, False),
'r': (19, False),
u'ret.arr': (14, False),
'right arrow': (77, False),
's': (31, False),
'scroll lock': (70, False),
'shift': (54, False),
'space': (57, False),
u'suppr': (83, False),
't': (20, False),
'tab': (124, False),
'u': (22, False),
'up arrow': (72, False),
'v': (47, False),
u'ver.num': (69, False),
u'verr.maj': (58, False),
'w': (44, False),
u'windows droite': (92, False),
u'windows gauche': (91, False),
'x': (45, False),
'y': (21, False),
'z': (17, False),
'zoom': (98, False),
u'\xa3': (27, True),
u'\xa7': (53, True),
u'\xa8': (26, True),
u'\xb0': (12, True),
u'\xb2': (41, False),
u'\xb5': (43, True),
u'\xe0': (11, False),
u'\xe7': (10, False),
u'\xe8': (8, False),
u'\xe9': (3, False),
u'\xf9': (40, False)}
from keyboard.
shift
is there, near the end, mapping to key scan code 54. Are you sure press('shift+a')
is not working? Is the error the same one as before (shift not mapped to any key
)? Did you restart your program since updating the package version?
Sorry for the basic questions, but it looks like everything is alright.
from keyboard.
Well.. 'shift' is working. I had a typo my brain did'nt want to see.
So, I can now use either 'shift' or 'maj'.
from keyboard.
Oh, that's a relief. Otherwise it would have been a tricky problem.
Yes, you can now use 'shift' or 'maj', but try not to rely on it or your code may not working on different installations.
Thank you for reporting this issue, it certainly made the life of everyone using this library with non-English Windows much better. I'm going to close this issue, but if you have any further problems or suggestions don't hesitate to comment here, open another issue or send me an email.
from keyboard.
I don't intend to use 'maj'. I was just reporting the fact that it is working. That's great.
It looks like some keys are missing in non french description :
- 'windows droite'
- 'windows gauche'
- '+ (pave num.)'
- '- (pave num.)'
...
pave num. = numpad
from keyboard.
I've experimented with numbers and got inexpected, but maybe correct, results.
Using '1' gives '&'. '2' gives... something (not sure of the result). '3' gives '"'...
On a french keyboard, numbers (above letters, not on keypad) are accessible with 'shift' :
- 1 : shitf+&
- 2 : shift+é
- 3 : shift+"
...
Is this behaviour correct ?
from keyboard.
The +
and -
names were already mapped to a key (shift+some key, most likely), so a translation was not needed. The Windows key does seem to be missing, but if it's not being reported as a virtual key I don't know what could be done.
The name of the keys on the events are used mainly for debugging. They should be legible (so 1
is preferred to !
), so this is something to be fixed, but it shouldn't affect the behavior of any function (hotkeys, abbreviations, recordings).
To check the key names you can do (Python3):
import keyboard
keyboard.hook(print)
input()
This should print every event received until you press enter.
Just to be clear, are the functions working as expected? Can you press('1')
, or add_hotkey('shift+2')
? If not then that's much more serious and I'll reopen the issue right away.
from keyboard.
I don't know what is the expected behaviour. I'll let you judge by yourself.
Actual issues are at the end.
Output of the excerpt of code :
-
Pressing '&'
KeyboardEvent(& down)
KeyboardEvent(& up) -
Pressing '1'
KeyboardEvent(maj down)
KeyboardEvent(& down)
KeyboardEvent(& up)
KeyboardEvent(maj up) -
Pressing 'Windows + e' (left)
KeyboardEvent(windows gauche down)
KeyboardEvent(e down)
KeyboardEvent(e up)
KeyboardEvent(windows gauche up) -
Pressing '1' (numpad)
KeyboardEvent(1 (pave num.) down)
KeyboardEvent(1 (pave num.) up)
keyboard.press('1') gives '&'
keyboard.press('shift+1') gives '1'
keyboard.press('&') gives '&'
keyboard.press('shift+&') gives '1'
keyboard.press("1 (pave num.)") goes to end of line
keyboard.press("windows + e")
Traceback (most recent call last):
File "Z:\Eclipse\GamepadToKey\src\test.py", line 18, in
keyboard.press("windows + e")
File "Z:\Eclipse\GamepadToKey\src\keyboard__init__.py", line 531, in press
send(combination, True, False)
File "Z:\Eclipse\GamepadToKey\src\keyboard__init__.py", line 523, in send
os_keyboard.press(to_scan_code(key))
File "Z:\Eclipse\GamepadToKey\src\keyboard__init_.py", line 501, in to_scan_code
scan_code, modifiers = _os_keyboard.map_char(_normalize_name(key))
File "Z:\Eclipse\GamepadToKey\src\keyboard_winkeyboard.py", line 418, in map_char
raise ValueError('Key name {} is not mapped to any known key.'.format(repr(name)))
ValueError: Key name 'windows' is not mapped to any known key.
keyboard.press("shift + 1 (pave num.)")
Traceback (most recent call last):
File "Z:\Eclipse\GamepadToKey\src\test.py", line 17, in
keyboard.press("shift + 1 (pave num.)")
File "Z:\Eclipse\GamepadToKey\src\keyboard__init__.py", line 531, in press
send(combination, True, False)
File "Z:\Eclipse\GamepadToKey\src\keyboard__init__.py", line 523, in send
os_keyboard.press(to_scan_code(key))
File "Z:\Eclipse\GamepadToKey\src\keyboard__init_.py", line 501, in to_scan_code
scan_code, modifiers = _os_keyboard.map_char(_normalize_name(key))
File "Z:\Eclipse\GamepadToKey\src\keyboard_winkeyboard.py", line 418, in map_char
raise ValueError('Key name {} is not mapped to any known key.'.format(repr(name)))
ValueError: Key name '1(pavenum.)' is not mapped to any known key.
Please note that space have been removed between 1 and (
from keyboard.
The pavenum
part is not supported. Currently you can`t specify if you want the keypad key or not, or even if you want the left or right key. If there is ever a need I'll revisit this decision.
The missing windows
key is certainly a bug, though I don`t know what could have happened. I'm reopening the issue because of this.
And lastly, what do the first excerpts mean? Did you press the 1
key on your keyboard and it issued 4 events, or did you do press('1')
? If the latter, did it type the key correctly?
from keyboard.
I am interrested in numpad support.
And lastly, what do the first excerpts mean?
import keyboard
keyboard.hook(print)
input()
Then hit keys
from keyboard.
I am interrested in numpad support.
What functionality do you need? Do you need to differentiate between numpad 1
and upper row 1
by name? Emit a press
event for the numpad 1
key specifically? Something else? Note you can already do this manually by using the scan code, what is missing is the name mapping.
And I just checked what the French layout looks like, and I was surprised:
I realize you were telling me this before but I didn't understand. Now it makes perfect sense for the 1
key to report as &
, because that's the unmodified state of that key. And if you had to hold shift
to type 1
it also makes sense that it emitted four events. So it looks alright to me. Did you expect something different?
from keyboard.
What functionality do you need? Do you need to differentiate between numpad 1 and upper row 1 by name? Emit a press event for the numpad 1 key specifically? Something else? Note you can already do this manually by using the scan code, what is missing is the name mapping.
Yes, differenciating numpad '1' from the other one by a specific name.
Using a name instead of scan code is great. A name is easier to remember.
I realize you were telling me this before but I didn't understand. Now it makes perfect sense for the 1 key to report as &, because that's the unmodified state of that key. And if you had to hold shift to type 1 it also makes sense that it emitted four events. So it looks alright to me. Did you expect something different?
I've been disapointed when I used keyboard.press('1') and got '&' as a result. At first, I didn't understood we are in fact using scancodes here. In the context of scancode, this makes sense.
PS : Just to let you know, I am writting a software for my son. The aim is to let him play games (designed to be played with a keyboard) with a gamepad. So, my little software captures gamepad event (using pygame) and translate them to keys (using keyboard of course).
from keyboard.
I've been disapointed when I used keyboard.press('1') and got '&' as a result. At first, I didn't understood we are in fact using scancodes here. In the context of scancode, this makes sense.
The press
function is based on physical keys, but there are other functions that are based on characters. write('1')
for example should hold shift, press the key, and release shift, with the goal of producing a 1
character. Is that what you are looking for? In this case the documentation could be clearer.
PS : Just to let you know, I am writting a software for my son. The aim is to let him play games (designed to be played with a keyboard) with a gamepad. So, my little software captures gamepad event (using pygame) and translate them to keys (using keyboard of course).
That sounds awesome (: I'll do my best to help.
from keyboard.
The press function is based on physical keys, but there are other functions that are based on characters. write('1') for example should hold shift, press the key, and release shift, with the goal of producing a 1 character. Is that what you are looking for? In this case the documentation could be clearer.
At first, I didn't noticed the difference between write() and press(). I have not tried write() for now. I might have to use it since some games use scancodes and others use characters.
I'll do my best to help.
You already did it 😉
from keyboard.
Hi @NicoPy
You can now differentiate between keypad 1 and top-row 1 by the event.is_keypad
attribute. It's not on the name as you wished, but I think this will cause less confusion for other users who are looking for characters. This feature is available on version 0.9.6.
I'm closing the issue, but if you still have any problems (or think I didn't address something) feel free to reopen it or send me an email.
from keyboard.
Hi @boppreh
That's an interesting feature but I guess this is only usable with received events, not generated events.
Right ?
from keyboard.
Correct. Do you have any use for generating key presses with such specificity?
from keyboard.
Yes.
from keyboard.
Ok. I'm curious, but I won't push.
This change shouldn't be too hard, I'll keep you updated at #32 .
from keyboard.
Should be fixed now, please give it a try: press('keypad 5')
Not sure if it makes any difference on Windows, though.
from keyboard.
How can i do numlock on and off using keyboard module?
from keyboard.
Related Issues (20)
- suppress=True breaks Windows Start Menu HOT 3
- Key name '~' in not mapped to any known key
- 'right alt' and 'left alt' parsable hotkeys behaves the same as the 'alt' parsable hotkey on Windows
- suppress=True doesn't work with read_hotkey and on_release_key HOT 1
- How to stop `Keyboard.hook` hooking `keyboard.send` or `keyboard.write`?
- Alt Down not detected with Streamdeck
- Returns upper and lower cases on Windows but only lower cases on Linux
- An OSError when the device is unplugged on RaspberrypiOS HOT 2
- Suddenly not working in mac os
- Periodicaly produce a TypeError: object of type 'NoneType' has no len()
- Cannot hold a key
- 'LMB + Ctrl' mulfunctions when `suppress = True`
- German and English Keyboard. Mixed letters (Z<-->Y)
- audio being muted when pressing "D" with this module HOT 1
- Can hotKey support double-clicking key like 'ctrl+ctrl'?
- calling keyboard.send() with a scan code produces wrong output
- Support language while in running
- Is Just Pressed
- suppress=True will cause a 1-second delay when pressing Ctrl, ALT, and other keys separately, such as running the ALT key in games
- Causes stutter / lag in game (Starcraft 2) when keys are being pressed
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from keyboard.