control - Detectando clics del mouse en ventanas usando python
python mouse and keyboard control (5)
La forma más WM_LBUTTONDBLCLK
de hacerlo es manejar el mensaje WM_LBUTTONDBLCLK
.
Para que esto se envíe, 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 darle algunas pistas.
¿Cómo puedo detectar clics del mouse sin importar la ventana en la que se encuentra el mouse?
Perfectamente en Python, pero si alguien puede explicarlo en cualquier lengua, podría ser capaz de resolverlo.
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 pygame.mouse.get_pos () 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/ )
Se puede acceder a Windows MFC, incluida la programación de la GUI, con python utilizando las extensiones de Python para Windows de Mark Hammond. Un extracto del libro O''Reilly del libro de Hammond y Robinson muestra cómo enganchar los mensajes del mouse, por ejemplo:
self.HookMessage(self.OnMouseMove,win32con.WM_MOUSEMOVE)
Raw MFC no es fácil ni obvio, pero buscar ejemplos de python en la web puede arrojar algunos ejemplos utilizables.
La única forma de detectar eventos de mouse fuera de su programa es instalar un enlace de Windows usando SetWindowsHookEx . El módulo pyHook encapsula 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 está instalado con el módulo para obtener más información sobre el parámetro del evento .
pyHook puede ser complicado de usar en un script de Python puro, ya que requiere una bomba de mensajes activa. Del tutorial :
Cualquier aplicación que desee recibir notificaciones de eventos de entrada globales debe tener una bomba de mensajes de Windows. La forma más fácil de obtener uno de estos es utilizar el método PumpMessages en el paquete de extensiones de Win32 para Python. [...] Cuando se ejecuta, este programa simplemente permanece inactivo y espera eventos de Windows. Si está utilizando un kit de herramientas GUI (por ejemplo, wxPython), este bucle es innecesario ya que el kit de herramientas proporciona el suyo propio.
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)
Ha sido un minuto caliente desde que se hizo esta pregunta, pero pensé que compartiría mi solución: acabo de utilizar los ctypes
módulo 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