From 8882c6c1731ac0bf2be5e019eb363c6c5c23a201 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Jul 2015 04:18:34 +0200 Subject: [PATCH 1/5] Fixed the windows code so it returns a string of letters or code, but the arrow keys and function keys don't return the correct sequences. I will fix that in the next version, but it will use a keys file with a dict. The current method of variables is not going to work very well for this. --- readchar/readchar.py | 1 - readchar/readchar_windows.py | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/readchar/readchar.py b/readchar/readchar.py index f96ae29..01042b0 100644 --- a/readchar/readchar.py +++ b/readchar/readchar.py @@ -6,7 +6,6 @@ import sys from . import key - if sys.platform.startswith('linux'): from .readchar_linux import readchar elif sys.platform == 'darwin': diff --git a/readchar/readchar_windows.py b/readchar/readchar_windows.py index b3170e1..5923f00 100644 --- a/readchar/readchar_windows.py +++ b/readchar/readchar_windows.py @@ -8,10 +8,7 @@ def readchar(blocking=False): "Get a single character on Windows." - while msvcrt.kbhit(): - msvcrt.getch() ch = msvcrt.getch() - while ch in '\x00\xe0': - msvcrt.getch() + if ch in '\000\xe0': ch = msvcrt.getch() - return ch.decode() + return repr(ch)[1:-1] From 09dd84ce66817d241f1873cc650421769f97e104 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Jul 2015 06:30:15 +0200 Subject: [PATCH 2/5] Added a dict of special keys in windows. All but 6 keys work and those 6 have 2 meanings. Find the dict of keys in the keys.py. The reason why there are 2 dicts is because there are 2 processing areas for keys and they overlap. The next task is to convert the linux and mac sets to fit into the same dict format. --- readchar/readchar_windows.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/readchar/readchar_windows.py b/readchar/readchar_windows.py index 5923f00..0b186ac 100644 --- a/readchar/readchar_windows.py +++ b/readchar/readchar_windows.py @@ -3,12 +3,23 @@ # http://code.activestate.com/recipes/134892/#c9 # Thanks to Stephen Chappell import msvcrt - +from keys import windows_keys, windows_special_keys def readchar(blocking=False): - "Get a single character on Windows." + """Get a single character on Windows.""" + ch = msvcrt.getch() + if ch in '\x00\xe0': + ch = msvcrt.getch() + ch = windows_special_keys.get(ch, ch) + ch = repr(ch)[1:-1] + if ch.startswith('\\') or ch == ' ': + ch = windows_keys.get(ch, ch) + return ch + +if __name__ == '__main__': + while True: + c = readchar() + print(c) - ch = msvcrt.getch() - if ch in '\000\xe0': - ch = msvcrt.getch() - return repr(ch)[1:-1] + if c == 'e': + break From e427a06be682eb409a799db1f8f312f8cc4ef848 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Jul 2015 06:45:28 +0200 Subject: [PATCH 3/5] forgot to add keys.py to the last commit! Here it is. --- readchar/keys.py | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 readchar/keys.py diff --git a/readchar/keys.py b/readchar/keys.py new file mode 100644 index 0000000..5dc31fb --- /dev/null +++ b/readchar/keys.py @@ -0,0 +1,102 @@ +#These following keys are ones that have 2 meanings. +#The first key command is the one that is not in the dict below: +#ctrl_i is tab +#ctrl_[ is escape +#ctrl_2 is ctrl_c +#ctrl_h is backspace +#ctrl_j is ctrl_enter +#ctrl_m is enter + +windows_special_keys = { +#Single keys: +'H': 'up', +'M': 'right', +'P': 'down', +'K': 'left', +';': 'f1', +'<': 'f2', +'=': 'f3', +'>': 'f4', +'?': 'f5', +'@': 'f6', +'A': 'f7', +'B': 'f8', +'C': 'f9', +'D': 'f10', +'S': 'delete', +#key combos +#shifted_keys +'T': 'shift_f1', +'U': 'shift_f2', +'V': 'shift_f3', +'W': 'shift_f4', +'X': 'shift_f5', +'Y': 'shift_f6', +'Z': 'shift_f7', +'[': 'shift_f8', +'\\': 'shift_f9', +']': 'shift_f10', +#ctrl_keys +'^': 'ctrl_f1', +'_': 'ctrl_f2', +'`': 'ctrl_f3', +'a': 'ctrl_f4', +'b': 'ctrl_f5', +'c': 'ctrl_f6', +'d': 'ctrl_f7', +'e': 'ctrl_f8', +'f': 'ctrl_f9', +'g': 'ctrl_f10', +'\x8d': 'ctrl_up', +'\x91': 'ctrl_down', +'s': 'ctrl_left', +'t': 'ctrl_right', +} + +windows_keys = { +#Single keys: +'\\x1b': 'escape', +' ': 'space', +'\\x85': 'f11', +'\\x86': 'f12', +'\\x08': 'backspace', +'\\r': 'enter', +'\\t': 'tab', +#key combos +#shifted_keys +'\\x87': 'shift_f11', +'\\x88': 'shift_f12', +#ctrl_keys +'\\x89': 'ctrl_f11', +'\\x8a': 'ctrl_f12', +'\\x93': 'ctrl_delete', +'\\n': 'ctrl_enter', +'\\x94': 'ctrl_tab', +'\\x7f': 'ctrl_backspace', +'\\x1c': 'ctrl_\\', +'\\x1d': 'ctrl_]', +#ctrl letters +'\\x01': 'ctrl_a', +'\\x02': 'ctrl_b', +'\\x03': 'ctrl_c', +'\\x04': 'ctrl_d', +'\\x05': 'ctrl_e', +'\\x06': 'ctrl_f', +'\\x07': 'ctrl_g', +'\\x0b': 'ctrl_k', +'\\x0c': 'ctrl_l', +'\\x0e': 'ctrl_n', +'\\x0f': 'ctrl_o', +'\\x10': 'ctrl_p', +'\\x11': 'ctrl_q', +'\\x12': 'ctrl_r', +'\\x13': 'ctrl_s', +'\\x14': 'ctrl_t', +'\\x15': 'ctrl_u', +'\\x16': 'ctrl_v', +'\\x17': 'ctrl_w', +'\\x18': 'ctrl_x', +'\\x19': 'ctrl_y', +'\\x1a': 'ctrl_z', +'\\\\': '\\', +} \ No newline at end of file From 121118d52b13f3acb67171ef08e77fc364b5ff07 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Jul 2015 07:09:24 +0200 Subject: [PATCH 4/5] Added the ability for readchar on windows to run either as raw_input does, waiting for a key, or check if there is a key and if there is process it, otherwise move on. Pass blocked=True if you wish for the program to wait for a key press, enter False (default) if you wish to only return a key if there is a key waiting. --- readchar/readchar_windows.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/readchar/readchar_windows.py b/readchar/readchar_windows.py index 0b186ac..4cd1b8a 100644 --- a/readchar/readchar_windows.py +++ b/readchar/readchar_windows.py @@ -5,7 +5,7 @@ import msvcrt from keys import windows_keys, windows_special_keys -def readchar(blocking=False): +def get_char(): """Get a single character on Windows.""" ch = msvcrt.getch() if ch in '\x00\xe0': @@ -16,10 +16,18 @@ def readchar(blocking=False): ch = windows_keys.get(ch, ch) return ch +def readchar(blocking=False): + """gets a character or combo on windows and returns a string. If blocking is True then it will catch ctrl+c and not have them end the program. It will also wait for a key to be pressed before continuing on with the loop.""" + if blocking: + return get_char() + else: + if msvcrt.kbhit(): + return get_char() + if __name__ == '__main__': while True: c = readchar() - print(c) - + if c: + print(c) if c == 'e': break From 605a877f499853ebd5342ae8b7d2ddd4e13d4986 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 23 Jul 2015 07:13:36 +0200 Subject: [PATCH 5/5] Added a blocking keyword in readchar. Pass True if you wish the program to wait for a char to be pressed and pass False if you wish the function to return only when there is a char on the queue. --- readchar/readchar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readchar/readchar.py b/readchar/readchar.py index 01042b0..21c72b5 100644 --- a/readchar/readchar.py +++ b/readchar/readchar.py @@ -16,9 +16,9 @@ raise NotImplemented('The platform %s is not supported yet' % sys.platform) -def readkey(getchar_fn=None): +def readkey(getchar_fn=None, blocking=True): getchar = getchar_fn or readchar - buffer = getchar(True) + buffer = getchar(blocking) while True: if buffer not in key.ESCAPE_SEQUENCES: