2008-10-03 12 views
16

Wie kann ich Mausklicks unabhängig vom Fenster der Maus erkennen?Erkennen von Mausklicks in Fenstern mit Python

Perfekt in Python, aber wenn jemand es in jeder Sprache erklären kann, könnte ich es herausfinden.

fand ich diese auf Microsofts Website: http://msdn.microsoft.com/en-us/library/ms645533(VS.85).aspx

Aber ich sehe nicht, wie ich erkennen kann, oder die Meldungen aufgelistet abholen.

Versuchte pygame der pygame.mouse.get_pos() Funktion wie folgt:

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

Das gibt nur 0,0. Ich bin nicht vertraut mit Pygame, fehlt etwas?

In jedem Fall würde ich eine Methode bevorzugen, ohne ein Drittanbieter-Modul zu installieren. (außer pywin32 http://sourceforge.net/projects/pywin32/)

+0

Welche UI Toolkit/Bibliothek verwenden Sie? –

+2

Ich denke, das sollte mit Win32ui und Ctypes möglich sein. Ich fand, dass ich die Mausposition mit windll.user32.GetCursorPos (Zeiger (pt_struct)) erhalten kann (für Details: http://monkut.webfactional.com/blog/archive/2008/10/2/python-win-mouse -Position) – monkut

Antwort

29

Die einzige Möglichkeit, Mausereignisse außerhalb Ihres Programms zu erkennen, ist die Installation eines Windows-Hooks mit SetWindowsHookEx. Das pyHook Modul kapselt die wesentlichen Details ein. Hier ist ein Beispiel, das die Position von jedem Mausklick gedruckt wird:

import pyHook 
import pythoncom 

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

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

Sie das überprüfen example.py-Skript, das für weitere Informationen über die Ereignis Parameter mit dem Modul installiert ist.

pyHook könnte in einem reinen Python-Skript schwierig zu verwenden sein, da es eine aktive Nachrichtenpumpe erfordert. Von der tutorial:

Jede Anwendung, die Meldungen der globalen Eingabeereignisse empfangen möchte eine Windows-Nachrichtensystem haben müssen. Die einfachste Möglichkeit, eine davon zu erhalten, ist Verwenden Sie die PumpMessages-Methode im Win32 Extensions-Paket für Python. [...] Wenn dieses Programm ausgeführt wird, sitzt es nur im Leerlauf und wartet auf Windows-Ereignisse. Wenn Sie ein GUI-Toolkit verwenden (z. B. wxPython), ist diese Schleife unnötig , da das Toolkit seine eigenen bietet.

+0

Beachten Sie, dass PyHook in der Zwischenzeit ziemlich rumgegangen ist zu https://sourceforge.net/projects/pyhook/ –

+0

Wenn Sie die 'ctypes' Bibliothek beenden und dann irgendwo im aktuellen Thread ausführen möchten: ' ctypes.windll.user32.PostQuitMessage (0) ' Dies beendet' pythoncom.PumpMessages() ' –

2

Die Windows-Art, es zu tun, ist die WM_LBUTTONDBLCLK Nachricht zu behandeln.

Damit dies gesendet werden kann, muss Ihre Fensterklasse mit dem Klassenstil CS_DBLCLKS erstellt werden.

Ich fürchte, ich weiß nicht, wie man das in Python anwendet, aber hoffentlich könnte es Ihnen einige Hinweise geben.

4

Windows MFC, einschließlich GUI-Programmierung, ist mit Python unter Verwendung der Python for Windows extensions von Mark Hammond zugänglich. An O'Reilly Book Excerpt von Hammonds und Robinsons book zeigt, wie Mausnachrichten einzuhaken, .e.g:

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

Raw MFC nicht einfach oder offensichtlich, aber die Bahn für Python Beispiele können einige verwendbare Beispiele ergeben.

10

Ich benutze win32api. Es funktioniert, wenn Sie auf ein beliebiges Fenster klicken.

# 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

Es ist eine heiße Minute gewesen, da diese Frage gestellt wurde, aber ich dachte, dass ich meine Lösung teilen würde: Ich habe nur das Einbaumodul ctypes. (Ich benutze 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