Detección de clics del mouse en windows usando python
Pregunta
¿Cómo puedo detectar los clics del mouse independientemente de la ventana en la que se encuentre el mouse?
Rendimiento en python, pero si alguien puede explicarlo en cualquier idioma, podría ser capaz de averiguarlo.
Encontré esto en el sitio de microsoft: http://msdn.microsoft.com/en-us/ library / ms645533 (VS.85) .aspx
Pero no veo cómo puedo detectar o recoger las notificaciones enumeradas.
Intenté usar la función pygame.mouse.get_pos () de pygame de la siguiente manera:
import pygame
pygame.init()
while True:
print pygame.mouse.get_pos()
Esto solo devuelve 0,0. No estoy familiarizado con pygame, ¿falta algo?
En cualquier caso, preferiría un método sin la necesidad de instalar un módulo de terceros. (aparte de pywin32 http://sourceforge.net/projects/pywin32/ )
Solución
La única forma de detectar eventos del mouse fuera de su programa es instalar un enlace de Windows usando SetWindowsHookEx . El módulo pyHook resume los detalles esenciales. Aquí hay una muestra que imprimirá la ubicación de cada clic del mouse:
import pyHook
import pythoncom
def onclick(event):
print event.Position
return True
hm = pyHook.HookManager()
hm.SubscribeMouseAllButtonsDown(onclick)
hm.HookMouse()
pythoncom.PumpMessages()
hm.UnhookMouse()
Puede consultar el script example.py que se instala con el módulo para obtener más información sobre el parámetro evento .
PyHook puede ser difícil de usar en un script de Python puro, ya que requiere un bombeo de mensajes activo. Del tutorial :
Cualquier aplicación que desee recibir Notificaciones de eventos de entrada global. debe tener una bomba de mensajes de Windows. los La forma más fácil de obtener uno de estos es utilizar el método PumpMessages en el Paquete Win32 Extensions para Python. [...] Cuando se ejecuta, este programa simplemente se sienta Inactivo y espera los eventos de Windows. Si está utilizando un kit de herramientas GUI (por ejemplo, wxPython), este bucle no es necesario ya que el kit de herramientas proporciona su propio.
Otros consejos
Yo uso win32api. Funciona al hacer clic en cualquier ventana.
# Code to check if left or right mouse buttons were pressed
import win32api
import time
state_left = win32api.GetKeyState(0x01) # Left button down = 0 or 1. Button up = -127 or -128
state_right = win32api.GetKeyState(0x02) # Right button down = 0 or 1. Button up = -127 or -128
while True:
a = win32api.GetKeyState(0x01)
b = win32api.GetKeyState(0x02)
if a != state_left: # Button state changed
state_left = a
print(a)
if a < 0:
print('Left Button Pressed')
else:
print('Left Button Released')
if b != state_right: # Button state changed
state_right = b
print(b)
if b < 0:
print('Right Button Pressed')
else:
print('Right Button Released')
time.sleep(0.001)
Se puede acceder a Windows MFC, incluida la programación de GUI, con python utilizando extensiones de Python para Windows por Mark Hammond. Extracto de un libro de O'Reilly de Hammond's y Robinson libro muestra cómo enganchar mensajes del mouse, .eg:
self.HookMessage(self.OnMouseMove,win32con.WM_MOUSEMOVE)
El MFC sin formato no es fácil ni obvio, pero la búsqueda de ejemplos de python en la web puede dar algunos ejemplos útiles.
Ha sido un momento caluroso desde que se hizo esta pregunta, pero pensé que compartiría mi solución: acabo de usar el módulo incorporado ctypes
. (Estoy usando Python 3.3 por cierto)
import ctypes
import time
def DetectClick(button, watchtime = 5):
'''Waits watchtime seconds. Returns True on click, False otherwise'''
if button in (1, '1', 'l', 'L', 'left', 'Left', 'LEFT'):
bnum = 0x01
elif button in (2, '2', 'r', 'R', 'right', 'Right', 'RIGHT'):
bnum = 0x02
start = time.time()
while 1:
if ctypes.windll.user32.GetKeyState(bnum) not in [0, 1]:
# ^ this returns either 0 or 1 when button is not being held down
return True
elif time.time() - start >= watchtime:
break
time.sleep(0.001)
return False
La manera en que Windows lo hace es manejar el mensaje WM_LBUTTONDBLCLK
.
Para que se envíe esto, su clase de ventana debe crearse con el estilo de clase CS_DBLCLKS
.
Me temo que no sé cómo aplicar esto en Python, pero espero que pueda darte algunos consejos.