Search code examples
pythonpython-2.7mouseeventkeyboard-eventspywin32

How to get mouse up/down/moved and key press events in Python


I've been working for a while on a Python 2.7 project written for Linux to add Windows support to it. I'm trying to figure out how to get the event for keyboard press and the mouse moving, being pressed, or being released. I installed the win32api and pyHook but I just can't figure how to get it right. Note that I want it to get the event no matter where it is, not just when its pressed in the command prompt for example. Here is how you would do it in linux:

def handle_event(self):
    """ This function is called when a xlib event is fired """

    data = reply.data

    while len(data):
        event, data = rq.EventField(None).parse_binary_value(data, self._display.display, None, None)

        if event.type == X.MotionNotify:
            if self._mouse_last_x != None:
                mouse_distance=math.sqrt((event.root_x-self._mouse_last_x)**2+(event.root_y-self._mouse_last_y)**2)
                self.send_event(('mouse_moved',mouse_distance))
            self._mouse_last_x,self._mouse_last_y = event.root_x,event.root_y

        if event.type == X.ButtonPress:
            print event.sequence_number,event._data,event._fields
            self.send_event(('button_down',event._data['detail']))

        elif event.type == X.ButtonRelease:
            print event.sequence_number,event._data,event._fields
            self.send_event(('button_up',event._data['detail']))

        elif event.type == X.KeyPress and event.sequence_number == 0:
            key = event.detail
            self.send_event(('keys_pressed',key,1))

def run(self):
    self.disable_keyboard_interrupt()
    root = self._display.screen().root
    ctx = self._display.record_create_context(
                0,
                [record.AllClients],
                [{
                        'core_requests': (0, 0),
                        'core_replies': (0, 0),
                        'ext_requests': (0, 0, 0, 0),
                        'ext_replies': (0, 0, 0, 0),
                        'delivered_events': (0, 0),
                        'device_events': (X.KeyReleaseMask, X.PointerMotionMask),
                        'errors': (0, 0),
                        'client_started': False,
                        'client_died': False,
                }])

    self._display.record_enable_context(ctx, self.handle_event)

I just can't seem to figure out how to get it like this for Windows with any library.


Solution

  • There is Win32 API function SetWindowsHookEx.

    Example on Python: Applying low-level keyboard hooks with Python and SetWindowsHookExA

    pyHook is also good package for 32-bit Python (it's a bit outdated and you need some efforts to re-build it for x64 using MinGW). Example: Detecting Mouse clicks in windows using python