2015-09-25 30 views
8

Sto scrivendo un programma che si collega al software di progettazione, come un plugin esterno, quindi monitora i movimenti del mouse e gli eventi. Prenderà le azioni in base allo stato degli eventi del mouse del software collegato.Ottieni eventi del mouse all'esterno della finestra di Tkinter in Python

L'idea è che l'applicazione esterna abbia la capacità di interfacciarsi a più programmi simili invece di plugin specifici del programma.

Il prototipo, e potenzialmente il software di produzione, viene scritto in python utilizzando la libreria GUI Tkinter. Il tentativo è di renderlo semplice e portatile.

Ero facilmente in grado di afferrare la posizione del mouse di livello "OS" (vero schermo X, Y) senza che la finestra di Tkinter necessitasse di essere attiva. Il mio problema è che non sto trovando un modo per ottenere facilmente gli eventi del mouse da Tkinter. Posso solo raccogliere eventi quando oltre la finestra attiva di Tkinter.

Tkinter fornisce questo per la posizione del mouse:

coord = self.gui.winfo_pointerxy() 

non riesco a trovare simile per gli eventi del mouse. Esistono librerie come selfspy e Pymouse (ora parte di PyUserInput) che monitorano gli eventi, ma sono principalmente per il controllo dei dispositivi di input. La mia idea di backup è di usare queste librerie come riferimento per scrivere il mio programma di monitoraggio di input.

Le mie due piattaforme principali sono Mac e Windows.

Per farla breve:

  • Può tkinter darmi eventi del mouse quando gli eventi sono al di fuori della finestra Tkinter.
  • In caso contrario, ci sono altre opzioni "out of the box" che possono darmi eventi mouse X, Y e mouse.
  • Se non ci sono soluzioni pronte, alcune raccomandazioni su approccio e API. (Sembra Win32API per le finestre, quarzo e/o cacao in Mac e Xlib in Linux)

Grazie per il vostro tempo

risposta

1

questo modo si ottiene la posizione del mouse con Tkinter.

import Tkinter as tk 
root = tk.Tk() 

def motion(event): 
    x, y = event.x, event.y 
    print('{}, {}'.format(x, y)) 

root.bind('<Motion>', motion) 
root.mainloop() 

C'è un multipiattaforma modulo pyautogui (lavora per OS X, Windows, Linux).

pyautogui.posistion() //returns tuple with mouse x and y values 
         // same for python 3.x 

si riferiscono a questo article come rilevare i clic del mouse per finestre

+0

Grazie per l'invio. Questo sembra molto utile per la posizione e il movimento del mouse, ma gli eventi pulsante/clic all'esterno della finestra dell'app sono disponibili anche con queste API? L'esempio più semplice che riesco a pensare del tipo di funzionalità che sto cercando è un'applicazione di screenshot che è necessario fare clic e trascinare all'esterno della finestra dell'app. Devi essere in grado di vedere i clic del mouse insieme al movimento del mouse/posizione. – TravisT

+1

Fatta eccezione per le vedove, non penso ci siano metodi per ottenere eventi con clic del mouse fuori dalla finestra. –

1

Su Mac, l'opzione più semplice è probabilmente NSEvent s' addGlobalMonitorForEventsMatchingMask:handler:: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSEvent_Class/#//apple_ref/occ/clm/NSEvent/addGlobalMonitorForEventsMatchingMask:handler:

Si noti che questo è specifico per eventi inviati a altre applicazioni e non le tue.

A un livello inferiore, è possibile anche utilizzare i tocchi evento Quartz.Semplice esempio utilizzando PyObjC:

from Quartz import CGEventTapCreate 
# ...etc. 

def listen_for_mouse_events(): 
    mouse_tap = CGEventTapCreate(
    kCGSessionEventTap, 
    kCGHeadInsertEventTap, 
    kCGEventTapOptionListenOnly, 
    CGEventMaskBit(kCGEventLeftMouseDown) | CGEventMaskBit(kCGEventLeftMouseUp), 
    on_mouse_event, 
    None 
    ) 
    runLoopSource = CFMachPortCreateRunLoopSource(None, mouse_tap, 0) 
    CFRunLoopAddSource(
    CFRunLoopGetCurrent(), 
    runLoopSource, 
    kCFRunLoopDefaultMode 
) 
    CGEventTapEnable(mouse_tap, True) 

def on_mouse_event(proxy, event_type, event, refcon): 
    location = CGEventGetLocation(event) 
    if (event_type == kCGEventLeftMouseDown): 
    pass 
    elif (event_type == kCGEventLeftMouseUp): 
    pass 

(temo non posso commentare in dettaglio per quanto riguarda una soluzione di Windows.)