Detectando cliques de mouse no Windows usando python
Pergunta
Como posso detectar cliques no mouse, independentemente da janela em que o mouse está?
Perferabliy em Python, mas se alguém puder explicar em qualquer Langauge, eu poderá descobrir isso.
Eu encontrei isso no site da Microsoft:http://msdn.microsoft.com/en-us/library/ms645533(vs.85).aspx
Mas não vejo como posso detectar ou pegar as notificações listadas.
Tentei usar a função pygame.mouse.get_pos () da Pygame, da seguinte forma:
import pygame
pygame.init()
while True:
print pygame.mouse.get_pos()
Isso apenas retorna 0,0. Não estou familiarizado com o Pygame, está faltando algo?
Em qualquer caso, eu preferiria um método sem a necessidade de instalar um módulo de terceiros. (exceto Pywin32 http://sourceforge.net/projects/pywin32/ )
Solução
A única maneira de detectar eventos do mouse fora do seu programa é instalar um gancho do Windows usando SetWindowshookex. o Pyhook O módulo encapsula os detalhes da questão. Aqui está uma amostra que imprimirá a localização de cada clique do 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()
Você pode verificar o exemplo.py script que é instalado com o módulo para obter mais informações sobre o evento parâmetro.
O Pyhook pode ser complicado de usar em um script python puro, porque requer uma bomba de mensagem ativa. De tutorial:
Qualquer aplicativo que deseje receber notificações de eventos de entrada global deve ter uma bomba de mensagem do Windows. A maneira mais fácil de obter uma delas é usar o método de bombeamento no pacote Win32 Extensions para Python. [...] Quando executado, esse programa fica ocioso e aguarda os eventos do Windows. Se você estiver usando um kit de ferramentas da GUI (por exemplo, WxPython), esse loop não é desnecessário, pois o kit de ferramentas fornece o seu próprio.
Outras dicas
Eu uso o Win32API. Funciona ao clicar em qualquer janela.
# 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)
Windows MFC, incluindo programação da GUI, é acessível com python usando o Python para extensões do Windows Por Mark Hammond. Um exército de livro de O'Reilly de Hammond's e Robinson livro mostra como conectar mensagens do mouse, .eg:
self.HookMessage(self.OnMouseMove,win32con.WM_MOUSEMOVE)
O MFC bruto não é fácil ou óbvio, mas pesquisar na Web por exemplos de Python pode produzir alguns exemplos utilizáveis.
Faz um minuto quente desde que essa pergunta foi feita, mas pensei em compartilhar minha solução: acabei de usar o módulo embutido ctypes
. (Estou usando o Python 3.3 btw)
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
A maneira do Windows de fazer isso é lidar com o WM_LBUTTONDBLCLK
mensagem.
Para que isso seja enviado, sua classe de janela precisa ser criada com o CS_DBLCLKS
estilo de classe.
Receio não saber como aplicar isso no Python, mas espero que isso possa lhe dar algumas dicas.