Обнаружение щелчков мышью в окнах с использованием Python - PullRequest
21 голосов
/ 03 октября 2008

Как я могу обнаружить щелчки мыши независимо от того, в каком окне она находится?

Perferabliy в Python, но если кто-то может объяснить это в любом языке, я мог бы понять это.

Я нашел это на сайте Microsoft: http://msdn.microsoft.com/en-us/library/ms645533(VS.85).aspx

Но я не вижу, как я могу обнаружить или забрать перечисленные уведомления.

Пробовал с использованием функции pygame.mouse.get_pos () pygame следующим образом:

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

Это просто возвращает 0,0. Я не знаком с Pygame, чего-то не хватает?

В любом случае, я бы предпочел метод без необходимости установки стороннего модуля. (кроме pywin32 http://sourceforge.net/projects/pywin32/)

Ответы [ 5 ]

31 голосов
/ 04 октября 2008

Единственный способ обнаружить события мыши вне вашей программы - установить хук Windows, используя SetWindowsHookEx . Модуль pyHook инкапсулирует мельчайшие детали. Вот пример, который будет печатать местоположение каждого щелчка мыши:

import pyHook
import pythoncom

def onclick(event):
    print event.Position
    return True

hm = pyHook.HookManager()
hm.SubscribeMouseAllButtonsDown(onclick)
hm.HookMouse()
pythoncom.PumpMessages()
hm.UnhookMouse()

Вы можете проверить скрипт example.py , который устанавливается вместе с модулем, для получения дополнительной информации о параметре event .

pyHook может быть сложно использовать в чистом скрипте Python, потому что для этого требуется активная рассылка сообщений. Из учебника :

Любое приложение, которое хочет получить уведомления о глобальных событиях ввода должен иметь насос сообщений Windows. Самый простой способ получить один из них - это используйте метод PumpMessages в Пакет расширений Win32 для Python. [...] При запуске эта программа просто сидит простаивает и ждет событий Windows. Если Вы используете инструментарий GUI (например, wxPython), этот цикл не нужен поскольку инструментарий предоставляет свой собственный.

15 голосов
/ 30 января 2017

Я использую win32api. Работает при нажатии на любые окна.

# 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)
4 голосов
/ 03 октября 2008

Windows MFC, включая программирование с графическим интерфейсом, доступна через python с использованием расширений Python для Windows от Mark Hammond. Отрывок книги О'Рейли из книги Хаммонда и Робинсона показывает, как перехватывать сообщения мыши, например:

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

Необработанный или неочевидный MFC не прост, но поиск в Интернете примеров Python может привести к некоторым полезным примерам.

3 голосов
/ 06 октября 2017

Это горячая минута с тех пор, как был задан этот вопрос, но я решил поделиться своим решением: я просто использовал встроенный модуль ctypes. (Я использую Python 3.3 кстати)

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
2 голосов
/ 03 октября 2008

Способ Windows сделать это - обработать сообщение WM_LBUTTONDBLCLK.

Для того, чтобы это было отправлено, ваш класс окна должен быть создан в стиле класса CS_DBLCLKS.

Боюсь, я не знаю, как применить это в Python, но, надеюсь, это может дать вам некоторые подсказки.

...