2008-10-03 23 views
16

¿Cómo puedo detectar clics del mouse independientemente de la ventana en la que se encuentre el mouse?Detección de clics del mouse en ventanas con python

Perfectamente en python, pero si alguien puede explicarlo en cualquier idioma, podría ser capaz de resolverlo.

He encontrado 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.

intentado usar pygame.mouse.get_pos de pygame() la función de la siguiente manera:

import pygame 
pygame.init() 
while True: 
    print pygame.mouse.get_pos() 

Esto sólo 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. (que no sea pywin32 http://sourceforge.net/projects/pywin32/)

+0

¿Qué UI toolkit/library estás usando? –

+2

Creo que esto debería ser posible usando win32ui y ctypes. Descubrí que puedo obtener la posición del mouse con windll.user32.GetCursorPos (puntero (pt_struct)) (Para más detalles: http://monkut.webfactional.com/blog/archive/2008/10/2/python-win-mouse -position) – monkut

Respuesta

29

La única manera 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. He aquí una muestra que se imprimirá la ubicación de cada clic del ratón:

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 comprobar el example.py script que se instala con el módulo para obtener más información sobre el parámetro caso.

pyHook puede ser difícil de usar en un script de Python puro, ya que requiere una bomba de mensajes activa. Desde el tutorial:

Cualquier aplicación que desea recibir notificaciones de eventos de entrada globales debe tener un suministro de mensajes de Windows. La forma más fácil de obtener uno de estos es llamar al utilizando el método PumpMessages en el paquete de extensiones Win32 de para Python. [...] Cuando se ejecuta, este programa solo se encuentra 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.

+0

Tenga en cuenta que PyHook se ha movido bastante mientras tanto a https://sourceforge.net/projects/pyhook/ –

+0

Si desea salir de importar la biblioteca 'ctypes' y luego ejecutar en cualquier lugar del hilo actual: ' ctypes.windll.user32.PostQuitMessage (0) ' Esto terminará' pythoncom.PumpMessages() ' –

2

La forma más fácil 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.

4

Windows MFC, incluida la programación de la GUI, se puede acceder con python utilizando el Python for Windows extensions de Mark Hammond. An O'Reilly Book Excerpt de Hammond y Robinson de book muestra cómo conectar los mensajes de ratón, .e.g:

self.HookMessage(self.OnMouseMove,win32con.WM_MOUSEMOVE) 

Raw MFC no es fácil ni obvia, pero buscando en la web para ver ejemplos de pitón puede dar algunos ejemplos utilizables.

10

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) 
1

Ha sido un minuto caliente desde que se hizo esta pregunta, pero pensé que me gustaría compartir mi solución: acabo de utilizar 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 
Cuestiones relacionadas