pynput - ¿Cómo generar eventos de teclado en Python?
python keyboard events (6)
Mac OS
Aquí está la versión más completa de la respuesta de @Phylliida en forma de clase con el ejemplo del código:
#!/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)
Aquí está el código de demostración que usa la clase anterior:
# DEMO
if __name__ == ''__main__'':
keyboard = Keyboard()
if sys.platform == "darwin":
keyboard.Type(''Hello World!'')
elif sys.platform == "win32":
print("Error: Platform not supported!")
que simulará tipear Hello World!
texto en la ventana actual.
Puede ejecutar el código anterior como un script de shell. Verifique el enlace al archivo keyboard.py
.
Breve resumen:
Intento crear un programa que envíe eventos de teclado a la computadora para que, a todos los efectos, los eventos simulados se traten como teclas reales en el teclado.
publicación original:
Estoy buscando una forma de generar eventos de teclado usando Python.
Supongamos que la función recibe una tecla que debe simular presionando, como se muestra a continuación:
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
Lo anterior son obviamente ejemplos, pero lo que estoy buscando es una biblioteca, módulo o lo que sea, que puedo usar para simular eventos de teclado.
Nota : Esto es diferente a enviar caracteres a blocs de notas o ingresar texto en campos o cosas por el estilo. Quiero que el script de Python simule un evento de teclado real, la computadora pensará que realmente hay un evento de teclado.
Nota adicional:
No deseo enviar pulsaciones de teclas a la ventana activa. Quiero que el sistema crea que se presionan las teclas del teclado, sutil diferencia, ya que algunas ventanas activas no aceptan ciertas combinaciones de teclas, o si quería usar atajos de teclado. para procesos en segundo plano a través de mi script, no necesitan pasar por la ventana activa
Hasta ahora he visto estas cosas:
Generar eventos de teclado para la aplicación principal
¿Cómo generar eventos de tecla de teclado a través de Python?
Que eran todo sobre apple y no ayudaban en absoluto.
Y esto:
¿Cuál es la forma más fácil de simular el teclado y el mouse en Python?
Parece que podría ser lo que necesito, pero no puedo encontrar la biblioteca ni ninguna documentación.
También he buscado en más lugares, pero todavía no he encontrado una solución.
Cada plataforma tendrá un enfoque diferente para poder generar eventos de teclado. Esto se debe a que cada uno necesita hacer uso de las bibliotecas del sistema (y las extensiones del sistema). Para una solución multiplataforma, necesitaría tomar cada una de estas soluciones y envolverlas en una verificación de plataforma para realizar el enfoque adecuado.
Para Windows, es posible que pueda usar la extensión pywin32 . win32api.keybd_event
win32api.keybd_event
keybd_event (bVk, bScan, dwFlags, dwExtraInfo)
Simular un evento de teclado
Parámetros
bVk: BYTE - Código de clave virtual
bScan: BYTE - Código de exploración de hardware
dwFlags = 0: DWORD - Indicadores que especifican varias opciones de funciones
dwExtraInfo = 0: DWORD - Datos adicionales asociados con la pulsación de tecla
Deberá investigar pywin32 para saber cómo usarlo correctamente, ya que nunca lo he usado.
La idea de user648852 al menos para mí funciona muy bien para OS X, aquí está el código para hacerlo:
#!/usr/bin/env python
import time
from Quartz.CoreGraphics import CGEventCreateKeyboardEvent
from Quartz.CoreGraphics import CGEventPost
# Python releases things automatically, using CFRelease will result in a scary error
#from Quartz.CoreGraphics import CFRelease
from Quartz.CoreGraphics import kCGHIDEventTap
# From http://.com/questions/281133/controlling-the-mouse-from-python-in-os-x
# and from https://developer.apple.com/library/mac/documentation/Carbon/Reference/QuartzEventServicesRef/index.html#//apple_ref/c/func/CGEventCreateKeyboardEvent
def KeyDown(k):
keyCode, shiftKey = 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(k):
keyCode, shiftKey = toKeyCode(k)
time.sleep(0.0001)
CGEventPost(kCGHIDEventTap, CGEventCreateKeyboardEvent(None, keyCode, False))
time.sleep(0.0001)
def KeyPress(k):
keyCode, shiftKey = 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)
# From http://.com/questions/3202629/where-can-i-find-a-list-of-mac-virtual-key-codes
def toKeyCode(c):
shiftKey = False
# Letter
if c.isalpha():
if not c.islower():
shiftKey = True
c = c.lower()
if c in shiftChars:
shiftKey = True
c = shiftChars[c]
if c in keyCodeMap:
keyCode = keyCodeMap[c]
else:
keyCode = ord(c)
return keyCode, shiftKey
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
}
Sé que esta es una vieja pregunta, pero todavía está en la parte superior de Google.
Para python3 y python2 puedes usar pyautogui
( pip install pyautogui
)
from pyautogui import press, typewrite, hotkey
press(''a'')
typewrite(''quick brown fox'')
hotkey(''ctrl'', ''w'')
Se puede hacer usando 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
es la asignación de teclado virtual tal como lo define la API de Windows. La lista de códigos está disponible en MSDN: códigos de clave virtual (Windows)
Solo Windows: puede usar Ironpython o una biblioteca que le permita a cPython acceder a los frameworks .NET en Windows. Luego use la clase sendkeys de .NET o el send más general para simular una pulsación de tecla.
Sólo OS X: use PyObjC y luego use la llamada CGEventCreateKeyboardEvent
.
Divulgación completa: solo he hecho esto en OS X con Python, pero he usado .NET sendkeys (con C #) y eso funciona muy bien.