如何在Python中生成键盘事件?

发布于 2021-02-02 23:12:54

简短的摘要:

我正在尝试创建一个程序,该程序会将键盘事件发送到计算机,出于所有目的,模拟事件应视为键盘上的实际按键。

原始帖子:

我正在寻找一种使用python生成键盘事件的方法。

假定该函数收到一个必须模拟按下的键,如下所示:

keyboardevent('a') #lower case 'a'
keyboardevent('B') #upper case 'B'
keyboardevent('->') # right arrow key

def keyboardevent(key):
    #code that simulated 'key' being pressed on keyboard

上面显然是示例,但是我要寻找的是库,模块或其他任何可用来模拟键盘事件的库。

注意:这不同于将字符发送到记事本,或在字段等中输入文本。我希望python脚本模拟实际的键盘事件,计算机会认为确实存在键盘事件。

特别提示:

我不想将击键发送到活动窗口-我希望系统相信键盘的键被按下,这是细微的差别,因为某些活动窗口不接受某些键组合,或者我想使用键盘快捷键对于通过我的脚本进行的后台进程,它们不需要通过活动窗口

到目前为止,我已经看过这些东西:

为最前端的应用程序生成键盘事件

如何通过Python生成键盘按键事件?

都是关于苹果的,根本没有帮助。

还有这个:

在Python上模拟键盘和鼠标的最简单方法是什么?

似乎可能是我需要的,但是我找不到该库或任何文档。

我也搜索了更多地方,但尚未找到解决方案。

关注者
0
被浏览
100
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    可以使用ctypes完成:

    import ctypes
    from ctypes import wintypes
    import time
    
    user32 = ctypes.WinDLL('user32', use_last_error=True)
    
    INPUT_MOUSE    = 0
    INPUT_KEYBOARD = 1
    INPUT_HARDWARE = 2
    
    KEYEVENTF_EXTENDEDKEY = 0x0001
    KEYEVENTF_KEYUP       = 0x0002
    KEYEVENTF_UNICODE     = 0x0004
    KEYEVENTF_SCANCODE    = 0x0008
    
    MAPVK_VK_TO_VSC = 0
    
    # msdn.microsoft.com/en-us/library/dd375731
    VK_TAB  = 0x09
    VK_MENU = 0x12
    
    # C struct definitions
    
    wintypes.ULONG_PTR = wintypes.WPARAM
    
    class MOUSEINPUT(ctypes.Structure):
        _fields_ = (("dx",          wintypes.LONG),
                    ("dy",          wintypes.LONG),
                    ("mouseData",   wintypes.DWORD),
                    ("dwFlags",     wintypes.DWORD),
                    ("time",        wintypes.DWORD),
                    ("dwExtraInfo", wintypes.ULONG_PTR))
    
    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:
                self.wScan = user32.MapVirtualKeyExW(self.wVk,
                                                     MAPVK_VK_TO_VSC, 0)
    
    class HARDWAREINPUT(ctypes.Structure):
        _fields_ = (("uMsg",    wintypes.DWORD),
                    ("wParamL", wintypes.WORD),
                    ("wParamH", wintypes.WORD))
    
    class INPUT(ctypes.Structure):
        class _INPUT(ctypes.Union):
            _fields_ = (("ki", KEYBDINPUT),
                        ("mi", MOUSEINPUT),
                        ("hi", HARDWAREINPUT))
        _anonymous_ = ("_input",)
        _fields_ = (("type",   wintypes.DWORD),
                    ("_input", _INPUT))
    
    LPINPUT = ctypes.POINTER(INPUT)
    
    def _check_count(result, func, args):
        if result == 0:
            raise ctypes.WinError(ctypes.get_last_error())
        return args
    
    user32.SendInput.errcheck = _check_count
    user32.SendInput.argtypes = (wintypes.UINT, # nInputs
                                 LPINPUT,       # pInputs
                                 ctypes.c_int)  # cbSize
    
    # Functions
    
    def PressKey(hexKeyCode):
        x = INPUT(type=INPUT_KEYBOARD,
                  ki=KEYBDINPUT(wVk=hexKeyCode))
        user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
    
    def ReleaseKey(hexKeyCode):
        x = INPUT(type=INPUT_KEYBOARD,
                  ki=KEYBDINPUT(wVk=hexKeyCode,
                                dwFlags=KEYEVENTF_KEYUP))
        user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
    
    def AltTab():
        """Press Alt+Tab and hold Alt key for 2 seconds
        in order to see the overlay.
        """
        PressKey(VK_MENU)   # Alt
        PressKey(VK_TAB)    # Tab
        ReleaseKey(VK_TAB)  # Tab~
        time.sleep(2)
        ReleaseKey(VK_MENU) # Alt~
    
    if __name__ == "__main__":
        AltTab()
    
    

    hexKeyCode是Windows API定义的虚拟键盘映射。代码列表在MSDN上可用:虚拟键代码(Windows)



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看