Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting Mouse clicks in windows using python

How can I detect mouse clicks regardless of the window the mouse is in?

Perferabliy in python, but if someone can explain it in any langauge I might be able to figure it out.

I found this on microsoft's site: http://msdn.microsoft.com/en-us/library/ms645533(VS.85).aspx

But I don't see how I can detect or pick up the notifications listed.

Tried using pygame's pygame.mouse.get_pos() function as follows:

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

This just returns 0,0. I'm not familiar with pygame, is something missing?

In anycase I'd prefer a method without the need to install a 3rd party module. (other than pywin32 http://sourceforge.net/projects/pywin32/ )

like image 253
monkut Avatar asked Oct 03 '08 02:10

monkut


People also ask

Can Python simulate a mouse click?

Note: It is suggested to run these statements individually in a Python interactive shell such as a Jupyter notebook or IPython. The mouse. click() function does what its name suggests, it sends a click with the given button, try it out!

How do you automate a mouse click in Python?

This code uses moveTo() function, which takes x and y coordinates, and an optional duration argument. This function moves your mouse pointer from it's current location to x, y coordinate, and takes time as specified by duration argument to do so.


Video Answer


3 Answers

The only way to detect mouse events outside your program is to install a Windows hook using SetWindowsHookEx. The pyHook module encapsulates the nitty-gritty details. Here's a sample that will print the location of every mouse click:

import pyHook import pythoncom  def onclick(event):     print event.Position     return True  hm = pyHook.HookManager() hm.SubscribeMouseAllButtonsDown(onclick) hm.HookMouse() pythoncom.PumpMessages() hm.UnhookMouse() 

You can check the example.py script that is installed with the module for more info about the event parameter.

pyHook might be tricky to use in a pure Python script, because it requires an active message pump. From the tutorial:

Any application that wishes to receive notifications of global input events must have a Windows message pump. The easiest way to get one of these is to use the PumpMessages method in the Win32 Extensions package for Python. [...] When run, this program just sits idle and waits for Windows events. If you are using a GUI toolkit (e.g. wxPython), this loop is unnecessary since the toolkit provides its own.

like image 55
efotinis Avatar answered Sep 16 '22 14:09

efotinis


I use win32api. It works when clicking on any windows.

# 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) 
like image 30
Markacho Avatar answered Sep 16 '22 14:09

Markacho


It's been a hot minute since this question was asked, but I thought I'd share my solution: I just used the built-in module ctypes. (I'm using 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
like image 38
diligar Avatar answered Sep 18 '22 14:09

diligar