Detecting key presses

peter peter.mosley at talk21.com
Mon Jun 19 08:40:43 EDT 2006


Not a stupid question at all - its something I was looking for, and was
(and still am) surprised not to find a cross platform implementation.
It must be possible - for a short while I dabbled with yabasic and
there the same source code would recognise a keypress in both Windows
and Linux.

My solution was:-

    # Await key and return code - dos only
    def _keycode_msvcrt(self):
        #Loop till key pressed
        while 1:
            if msvcrt.kbhit():
                k=ord(msvcrt.getch())
                if k==0 or k==224:            #Special keys
                   k=1000+ord(msvcrt.getch()) #return 1000+ 2nd code
                pass
                break
            pass
        pass
        return k

    # Await key and return code - linux only
    def _keycode_linux2(self):
        # Loop till key pressed
        # Set up keycode list
        a=[0,0,0,0,0,0]

        # Press a key and populate list
        try:
            os.system('stty -icanon')
            os.system('stty -echo')
            a[0]=ord(sys.stdin.read(1))
            if a[0]==27:
a[1]=ord(sys.stdin.read(1))
            if a[1]==91:
a[2]=ord(sys.stdin.read(1))
            if (a[2]>=49 and a[2]<=54) or a[2]==91:
a[3]=ord(sys.stdin.read(1))
            if a[3]>=48 and a[3]<=57:
a[4]=ord(sys.stdin.read(1))
        finally:
            os.system('stty echo')
            os.system('stty icanon')

        # Decode keypress
        if   a==[ 10,  0,  0,   0,   0, 0]: k=  13   # Enter
        elif a==[ 27, 27,  0,   0,   0, 0]: k=  27   # Esc (double
press)
        elif a==[ 27, 91, 91,  65,   0, 0]: k=1059   # F1
        elif a==[ 27, 91, 91,  66,   0, 0]: k=1060   # F2
        elif a==[ 27, 91, 91,  67,   0, 0]: k=1061   # F3
        elif a==[ 27, 91, 91,  68,   0, 0]: k=1062   # F4
        elif a==[ 27, 91, 91,  69,   0, 0]: k=1063   # F5
        elif a==[ 27, 91, 49,  55, 126, 0]: k=1064   # F6
        elif a==[ 27, 91, 49,  56, 126, 0]: k=1065   # F7
        elif a==[ 27, 91, 49,  57, 126, 0]: k=1066   # F8
        elif a==[ 27, 91, 50,  48, 126, 0]: k=1067   # F9
        elif a==[ 27, 91, 50,  49, 126, 0]: k=1068   # F10
        elif a==[ 27, 91, 50,  51, 126, 0]: k=1133   # F11
        elif a==[ 27, 91, 50,  52, 126, 0]: k=1134   # F12
        elif a==[ 27, 91, 50, 126,   0, 0]: k=1082   # Ins
        elif a==[ 27, 91, 51, 126,   0, 0]: k=1083   # Del
        elif a==[ 27, 91, 49, 126,   0, 0]: k=1071   # Home
        elif a==[ 27, 91, 52, 126,   0, 0]: k=1079   # End
        elif a==[ 27, 91, 53, 126,   0, 0]: k=1073   # Pg Up
        elif a==[ 27, 91, 54, 126,   0, 0]: k=1081   # Pg Dn
        elif a==[ 27, 91, 65,   0,   0, 0]: k=1072   # Up
        elif a==[ 27, 91, 66,   0,   0, 0]: k=1080   # Down
        elif a==[ 27, 91, 68,   0,   0, 0]: k=1075   # Left
        elif a==[ 27, 91, 67,   0,   0, 0]: k=1077   # Right
        elif a==[127,  0,  0,   0,   0, 0]: k=   8   # Backspace
        else:                               k=a[0]   # Ascii code

        # Done
        return k


    # Return key code
    def key(self,case='NONE'):

        # Get OS name and call platform specific function
        a=sys.platform
        if a=='linux2':                       #Linux (works on Fedora
Core 1 and 3)
            k=self._keycode_linux2()
        elif a=='win32':                      #windows
            k=self._keycode_msvcrt()
        else:                                 #unknown
            k=ord(raw_input())

        # Adjust case
        if case=='UPPER':
             if k>=97 and k<=122:
                  k=k-32
        if case=='LOWER':
             if k>=65 and k<=90:
                  k=k+32

        # Done
        return k

A bit clumsy, I know (for example it needs a a double press to
recognise the escape key), and I'm not sure I understand why it works,
but for me it was a passable solution.

Peter




More information about the Python-list mailing list