How to generate keyboard events in Python?

后端 未结 11 1063
有刺的猬
有刺的猬 2020-11-22 14:55

short summary:

I am trying to create a program that will send keyboard events to the computer that for all purposes the simulated events should be t

相关标签:
11条回答
  • 2020-11-22 15:31

    For both python3 and python2 you can use pyautogui (pip install pyautogui)

    from pyautogui import press, typewrite, hotkey
    
    press('a')
    typewrite('quick brown fox')
    hotkey('ctrl', 'w')
    

    It's also crossplatform with Windows, OSX, and Ubuntu LTS.

    0 讨论(0)
  • 2020-11-22 15:31

    regarding the recommended answer's code,

    For my bot the recommended answer did not work. This is because I'm using Chrome which is requiring me to use KEYEVENTF_SCANCODE in my dwFlags.

    To get his code to work I had to modify these code blocks:

    class KEYBDINPUT(ctypes.Structure):
        _fields_ = (("wVk",         wintypes.WORD),
                    ("wScan",       wintypes.WORD),
                    ("dwFlags",     wintypes.DWORD),
                    ("time",        wintypes.DWORD),
                    ("dwExtraInfo", wintypes.ULONG_PTR))
    
        def __init__(self, *args, **kwds):
            super(KEYBDINPUT, self).__init__(*args, **kwds)
            # some programs use the scan code even if KEYEVENTF_SCANCODE
            # isn't set in dwFflags, so attempt to map the correct code.
            #if not self.dwFlags & KEYEVENTF_UNICODE:l
                #self.wScan = user32.MapVirtualKeyExW(self.wVk,
                                                     #MAPVK_VK_TO_VSC, 0)
                # ^MAKE SURE YOU COMMENT/REMOVE THIS CODE^
    
    def PressKey(keyCode):
        input = INPUT(type=INPUT_KEYBOARD,
                  ki=KEYBDINPUT(wScan=keyCode,
                                dwFlags=KEYEVENTF_SCANCODE))
        user32.SendInput(1, ctypes.byref(input), ctypes.sizeof(input))
    
    def ReleaseKey(keyCode):
        input = INPUT(type=INPUT_KEYBOARD,
                  ki=KEYBDINPUT(wScan=keyCode,
                                dwFlags=KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP))
        user32.SendInput(1, ctypes.byref(input), ctypes.sizeof(input))
    
    time.sleep(5) # sleep to open browser tab
    PressKey(0x26) # press right arrow key
    time.sleep(2) # hold for 2 seconds
    ReleaseKey(0x26) # release right arrow key
    
    

    I hope this helps someone's headache!

    0 讨论(0)
  • 2020-11-22 15:32

    macOS

    Here is the more complete version of @Phylliida answer in form of class with code example:

    #!/usr/bin/python
    # Script simulating keyboard events in macOS.
    # See: https://stackoverflow.com/q/13564851/55075
    
    import sys
    import time
    from Quartz.CoreGraphics import CGEventCreateKeyboardEvent
    from Quartz.CoreGraphics import CGEventPost
    from Quartz.CoreGraphics import kCGHIDEventTap
    #from Quartz.CoreGraphics import CFRelease # Python releases things automatically.
    
    class Keyboard():
        shiftChars = {
            '~': '`',
            '!': '1',
            '@': '2',
            '#': '3',
            '$': '4',
            '%': '5',
            '^': '6',
            '&': '7',
            '*': '8',
            '(': '9',
            ')': '0',
            '_': '-',
            '+': '=',
            '{': '[',
            '}': ']',
            '|': '\\',
            ':': ';',
            '"': '\'',
            '<': ',',
            '>': '.',
            '?': '/'
        }
    
    
        keyCodeMap = {
            'a'              : 0x00,
            's'              : 0x01,
            'd'              : 0x02,
            'f'              : 0x03,
            'h'              : 0x04,
            'g'              : 0x05,
            'z'              : 0x06,
            'x'              : 0x07,
            'c'              : 0x08,
            'v'              : 0x09,
            'b'              : 0x0B,
            'q'              : 0x0C,
            'w'              : 0x0D,
            'e'              : 0x0E,
            'r'              : 0x0F,
            'y'              : 0x10,
            't'              : 0x11,
            '1'              : 0x12,
            '2'              : 0x13,
            '3'              : 0x14,
            '4'              : 0x15,
            '6'              : 0x16,
            '5'              : 0x17,
            '='              : 0x18,
            '9'              : 0x19,
            '7'              : 0x1A,
            '-'              : 0x1B,
            '8'              : 0x1C,
            '0'              : 0x1D,
            ']'              : 0x1E,
            'o'              : 0x1F,
            'u'              : 0x20,
            '['              : 0x21,
            'i'              : 0x22,
            'p'              : 0x23,
            'l'              : 0x25,
            'j'              : 0x26,
            '\''             : 0x27,
            'k'              : 0x28,
            ';'              : 0x29,
            '\\'             : 0x2A,
            ','              : 0x2B,
            '/'              : 0x2C,
            'n'              : 0x2D,
            'm'              : 0x2E,
            '.'              : 0x2F,
            '`'              : 0x32,
            'k.'             : 0x41,
            'k*'             : 0x43,
            'k+'             : 0x45,
            'kclear'         : 0x47,
            'k/'             : 0x4B,
            'k\n'            : 0x4C,
            'k-'             : 0x4E,
            'k='             : 0x51,
            'k0'             : 0x52,
            'k1'             : 0x53,
            'k2'             : 0x54,
            'k3'             : 0x55,
            'k4'             : 0x56,
            'k5'             : 0x57,
            'k6'             : 0x58,
            'k7'             : 0x59,
            'k8'             : 0x5B,
            'k9'             : 0x5C,
    
            # keycodes for keys that are independent of keyboard layout
            '\n'             : 0x24,
            '\t'             : 0x30,
            ' '              : 0x31,
            'del'            : 0x33,
            'delete'         : 0x33,
            'esc'            : 0x35,
            'escape'         : 0x35,
            'cmd'            : 0x37,
            'command'        : 0x37,
            'shift'          : 0x38,
            'caps lock'      : 0x39,
            'option'         : 0x3A,
            'ctrl'           : 0x3B,
            'control'        : 0x3B,
            'right shift'    : 0x3C,
            'rshift'         : 0x3C,
            'right option'   : 0x3D,
            'roption'        : 0x3D,
            'right control'  : 0x3E,
            'rcontrol'       : 0x3E,
            'fun'            : 0x3F,
            'function'       : 0x3F,
            'f17'            : 0x40,
            'volume up'      : 0x48,
            'volume down'    : 0x49,
            'mute'           : 0x4A,
            'f18'            : 0x4F,
            'f19'            : 0x50,
            'f20'            : 0x5A,
            'f5'             : 0x60,
            'f6'             : 0x61,
            'f7'             : 0x62,
            'f3'             : 0x63,
            'f8'             : 0x64,
            'f9'             : 0x65,
            'f11'            : 0x67,
            'f13'            : 0x69,
            'f16'            : 0x6A,
            'f14'            : 0x6B,
            'f10'            : 0x6D,
            'f12'            : 0x6F,
            'f15'            : 0x71,
            'help'           : 0x72,
            'home'           : 0x73,
            'pgup'           : 0x74,
            'page up'        : 0x74,
            'forward delete' : 0x75,
            'f4'             : 0x76,
            'end'            : 0x77,
            'f2'             : 0x78,
            'page down'      : 0x79,
            'pgdn'           : 0x79,
            'f1'             : 0x7A,
            'left'           : 0x7B,
            'right'          : 0x7C,
            'down'           : 0x7D,
            'up'             : 0x7E
        }
    
        # See: https://stackoverflow.com/q/3202629/55075
        def toKeyCode(self, c):
            shiftKey = False
            # Letter
            if c.isalpha():
                if not c.islower():
                    shiftKey = True
                    c = c.lower()
            if c in Keyboard.shiftChars:
                shiftKey = True
                c = Keyboard.shiftChars[c]
            if c in Keyboard.keyCodeMap:
                keyCode = Keyboard.keyCodeMap[c]
            else:
                keyCode = ord(c)
            return keyCode, shiftKey
    
        def KeyDown(self, k):
            keyCode, shiftKey = self.toKeyCode(k)
    
            time.sleep(0.0001)
    
            if shiftKey:
                CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, True))
                time.sleep(0.0001)
    
            CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, True))
            time.sleep(0.0001)
    
            if shiftKey:
                CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, False))
                time.sleep(0.0001)
    
        def KeyUp(self, k):
            keyCode, shiftKey = self.toKeyCode(k)
    
            time.sleep(0.0001)
    
            CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, False))
            time.sleep(0.0001)
    
        def KeyPress(self, k):
            keyCode, shiftKey = self.toKeyCode(k)
    
            time.sleep(0.0001)
    
            if shiftKey:
                CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, True))
                time.sleep(0.0001)
    
            CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, True))
            time.sleep(0.0001)
    
            CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, False))
            time.sleep(0.0001)
    
            if shiftKey:
                CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, 0x38, False))
                time.sleep(0.0001)
    
        def Type(self, text):
            for key in text:
                self.KeyDown(key)
                self.KeyUp(key)
    

    Here is the demo code using above class:

    # DEMO
    if __name__ == '__main__':
        keyboard = Keyboard()
        if sys.platform == "darwin":
            keyboard.Type('Hello World!')
        elif sys.platform == "win32":
            print("Error: Platform not supported!")
    

    which will simulate typing Hello World! text on the current window.

    You can run above code as a shell script. Check the link to the keyboard.py file.

    0 讨论(0)
  • 2020-11-22 15:33

    I tried lib keyboard and it works good on Windows. Below line helps me switch tabs in browser:

    keyboard.press_and_release('ctrl+tab')
    
    0 讨论(0)
  • 2020-11-22 15:40

    For Python2.7(windows32) I installed only pywin32-223. And I wrote simple python`s code:

    import win32api
    import time
    import win32con
    
    # simulate the pressing-DOWN "ARROW key" of 200 times
    
    for i in range(200):
       time.sleep(0.5)
       win32api.keybd_event(0x28, 0,0,0)
       time.sleep(.05)
       win32api.keybd_event(0x28,0 ,win32con.KEYEVENTF_KEYUP ,0)
    

    It can be checked if you run the code and immediately go to the notepad window (where the text already exists) and place the cursor on the top line.

    0 讨论(0)
提交回复
热议问题