Come controllare il mouse in Mac usando Python?
Domanda
Quale sarebbe il modo più semplice per spostare il mouse (e possibilmente fare clic) usando Python su OS X?
Questo è solo per la prototipazione rapida, non deve essere elegante.
Soluzione 3
Ho cercato il codice sorgente di Synergy per trovare la chiamata che genera eventi del mouse:
#include <ApplicationServices/ApplicationServices.h>
int to(int x, int y)
{
CGPoint newloc;
CGEventRef eventRef;
newloc.x = x;
newloc.y = y;
eventRef = CGEventCreateMouseEvent(NULL, kCGEventMouseMoved, newloc,
kCGMouseButtonCenter);
//Apparently, a bug in xcode requires this next line
CGEventSetType(eventRef, kCGEventMouseMoved);
CGEventPost(kCGSessionEventTap, eventRef);
CFRelease(eventRef);
return 0;
}
Ora per scrivere i collegamenti Python!
Altri suggerimenti
Prova il codice su questa pagina . Definisce un paio di funzioni, mousemove
e mouseclick
, che si collegano all'integrazione di Apple tra Python e le librerie Quartz della piattaforma.
Questo codice funziona su 10.6 e lo sto usando su 10.7. La cosa bella di questo codice è che genera eventi del mouse, cosa che alcune soluzioni no. Lo uso per controllare BBC iPlayer inviando eventi del mouse a posizioni note dei pulsanti nel loro Flash Player (molto fragile lo so). Gli eventi di spostamento del mouse, in particolare, sono richiesti, altrimenti il ??Flash player non nasconde mai il cursore del mouse. Funzioni come CGWarpMouseCursorPosition
non lo faranno.
from Quartz.CoreGraphics import CGEventCreateMouseEvent
from Quartz.CoreGraphics import CGEventPost
from Quartz.CoreGraphics import kCGEventMouseMoved
from Quartz.CoreGraphics import kCGEventLeftMouseDown
from Quartz.CoreGraphics import kCGEventLeftMouseDown
from Quartz.CoreGraphics import kCGEventLeftMouseUp
from Quartz.CoreGraphics import kCGMouseButtonLeft
from Quartz.CoreGraphics import kCGHIDEventTap
def mouseEvent(type, posx, posy):
theEvent = CGEventCreateMouseEvent(
None,
type,
(posx,posy),
kCGMouseButtonLeft)
CGEventPost(kCGHIDEventTap, theEvent)
def mousemove(posx,posy):
mouseEvent(kCGEventMouseMoved, posx,posy);
def mouseclick(posx,posy):
# uncomment this line if you want to force the mouse
# to MOVE to the click location first (I found it was not necessary).
#mouseEvent(kCGEventMouseMoved, posx,posy);
mouseEvent(kCGEventLeftMouseDown, posx,posy);
mouseEvent(kCGEventLeftMouseUp, posx,posy);
Ecco l'esempio di codice dalla pagina sopra:
##############################################################
# Python OSX MouseClick
# (c) 2010 Alex Assouline, GeekOrgy.com
##############################################################
import sys
try:
xclick=intsys.argv1
yclick=intsys.argv2
try:
delay=intsys.argv3
except:
delay=0
except:
print "USAGE mouseclick [int x] [int y] [optional delay in seconds]"
exit
print "mouse click at ", xclick, ",", yclick," in ", delay, "seconds"
# you only want to import the following after passing the parameters check above, because importing takes time, about 1.5s
# (why so long!, these libs must be huge : anyone have a fix for this ?? please let me know.)
import time
from Quartz.CoreGraphics import CGEventCreateMouseEvent
from Quartz.CoreGraphics import CGEventPost
from Quartz.CoreGraphics import kCGEventMouseMoved
from Quartz.CoreGraphics import kCGEventLeftMouseDown
from Quartz.CoreGraphics import kCGEventLeftMouseDown
from Quartz.CoreGraphics import kCGEventLeftMouseUp
from Quartz.CoreGraphics import kCGMouseButtonLeft
from Quartz.CoreGraphics import kCGHIDEventTap
def mouseEventtype, posx, posy:
theEvent = CGEventCreateMouseEventNone, type, posx,posy, kCGMouseButtonLeft
CGEventPostkCGHIDEventTap, theEvent
def mousemoveposx,posy:
mouseEventkCGEventMouseMoved, posx,posy;
def mouseclickposx,posy:
#mouseEvent(kCGEventMouseMoved, posx,posy); #uncomment this line if you want to force the mouse to MOVE to the click location first (i found it was not necesary).
mouseEventkCGEventLeftMouseDown, posx,posy;
mouseEventkCGEventLeftMouseUp, posx,posy;
time.sleepdelay;
mouseclickxclick, yclick;
print "done."
Prova questo codice:
#!/usr/bin/python
import objc
class ETMouse():
def setMousePosition(self, x, y):
bndl = objc.loadBundle('CoreGraphics', globals(),
'/System/Library/Frameworks/ApplicationServices.framework')
objc.loadBundleFunctions(bndl, globals(),
[('CGWarpMouseCursorPosition', 'v{CGPoint=ff}')])
CGWarpMouseCursorPosition((x, y))
if __name__ == "__main__":
et = ETMouse()
et.setMousePosition(200, 200)
funziona in OSX leopard 10.5.6
Quando volevo farlo, ho installato Jython e ho usato java.awt.Robot
classe. Se hai bisogno di creare uno script CPython questo ovviamente non è adatto, ma quando hai la flessibilità di scegliere qualsiasi cosa è una bella soluzione multipiattaforma.
import java.awt
robot = java.awt.Robot()
robot.mouseMove(x, y)
robot.mousePress(java.awt.event.InputEvent.BUTTON1_MASK)
robot.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK)
La libreria pynput
sembra la libreria attualmente meglio gestita. Ti consente di controllare e monitorare i dispositivi di input.
Ecco l'esempio per il controllo del mouse:
from pynput.mouse import Button, Controller
mouse = Controller()
# Read pointer position
print('The current pointer position is {0}'.format(
mouse.position))
# Set pointer position
mouse.position = (10, 20)
print('Now we have moved it to {0}'.format(
mouse.position))
# Move pointer relative to current position
mouse.move(5, -5)
# Press and release
mouse.press(Button.left)
mouse.release(Button.left)
# Double click; this is different from pressing and releasing
# twice on Mac OSX
mouse.click(Button.left, 2)
# Scroll two steps down
mouse.scroll(0, 2)
Il modo più semplice è usare PyAutoGUI.
Esempio:
-
Per ottenere la posizione del mouse:
>>> pyautogui.position() (187, 567)
-
Per spostare il mouse in una posizione specifica:
>>> pyautogui.moveTo(100,200)
-
Per attivare un clic del mouse:
>>> pyautogui.click()
Ulteriori dettagli: PyAutoGUI
Lo script python da geekorgy.com è fantastico, tranne che mi sono imbattuto in alcuni ostacoli da quando ho installato una nuova versione di Python. Quindi, ecco alcuni suggerimenti per gli altri che potrebbero essere alla ricerca di una soluzione.
Se hai installato Python 2.7 sul tuo Mac OS 10.6 hai alcune opzioni per far importare Python da Quartz.CoreGraphics:
A) Nel terminale, digita python2.6
invece di python
prima del percorso verso il lo script
B) Puoi installare PyObjC procedendo come segue:
- Installa easy_install da http://pypi.python.org/pypi/setuptools
- Nel terminale, digita
quale python
e copia il percorso su2.7
-
Quindi digitare
easy_install & # 8211; -prefix / Path / To / Python / Version pyobjc == 2.3
** ie.
easy_install & # 8211; -prefix /Library/Frameworks/Python.framework/Versions/2.7 pyobjc == 2.3
- All'interno del tipo di script
import objc
in alto -
Se easy_install non funziona la prima volta, potrebbe essere necessario installare prima il core:
** ie.
easy_install --prefix /Library/Frameworks/Python.framework/Versions/2.7 pyobjc-core == 2.3
C) Puoi reimpostare il tuo percorso Python sul Python originale di Mac OS:
- Nel terminale, digitare:
defaults write com.apple.versioner.python Versione 2.6
*** Inoltre, un modo rapido per scoprire le coordinate (x, y) sullo schermo:
- Premi
Comando + Maiusc + 4
(selezione schermata) - Il cursore mostra quindi le coordinate
- Quindi premi Esc per uscirne.
La soluzione migliore è utilizzare il pacchetto AutoPy . È estremamente semplice da usare e multipiattaforma per l'avvio.
Per spostare il cursore in posizione (200.200):
import autopy
autopy.mouse.move(200,200)
Usa CoreGraphics
dalla libreria Quartz, ad esempio:
from Quartz.CoreGraphics import CGEventCreate
from Quartz.CoreGraphics import CGEventGetLocation
ourEvent = CGEventCreate(None);
currentpos = CGEventGetLocation(ourEvent);
mousemove(currentpos.x,currentpos.y)
Ecco l'esempio completo usando la libreria Quartz
:
#!/usr/bin/python
import sys
from AppKit import NSEvent
import Quartz
class Mouse():
down = [Quartz.kCGEventLeftMouseDown, Quartz.kCGEventRightMouseDown, Quartz.kCGEventOtherMouseDown]
up = [Quartz.kCGEventLeftMouseUp, Quartz.kCGEventRightMouseUp, Quartz.kCGEventOtherMouseUp]
[LEFT, RIGHT, OTHER] = [0, 1, 2]
def position(self):
point = Quartz.CGEventGetLocation( Quartz.CGEventCreate(None) )
return point.x, point.y
def location(self):
loc = NSEvent.mouseLocation()
return loc.x, Quartz.CGDisplayPixelsHigh(0) - loc.y
def move(self, x, y):
moveEvent = Quartz.CGEventCreateMouseEvent(None, Quartz.kCGEventMouseMoved, (x, y), 0)
Quartz.CGEventPost(Quartz.kCGHIDEventTap, moveEvent)
def press(self, x, y, button=1):
event = Quartz.CGEventCreateMouseEvent(None, Mouse.down[button], (x, y), button - 1)
Quartz.CGEventPost(Quartz.kCGHIDEventTap, event)
def release(self, x, y, button=1):
event = Quartz.CGEventCreateMouseEvent(None, Mouse.up[button], (x, y), button - 1)
Quartz.CGEventPost(Quartz.kCGHIDEventTap, event)
def click(self, button=LEFT):
x, y = self.position()
self.press(x, y, button)
self.release(x, y, button)
def click_pos(self, x, y, button=LEFT):
self.move(x, y)
self.click(button)
def to_relative(self, x, y):
curr_pos = Quartz.CGEventGetLocation( Quartz.CGEventCreate(None) )
x += current_position.x;
y += current_position.y;
return [x, y]
def move_rel(self, x, y):
[x, y] = to_relative(x, y)
moveEvent = Quartz.CGEventCreateMouseEvent(None, Quartz.kCGEventMouseMoved, Quartz.CGPointMake(x, y), 0)
Quartz.CGEventPost(Quartz.kCGHIDEventTap, moveEvent)
Il codice sopra riportato si basa su questi file originali: Mouse.py
< code> mouseUtils.py .
Ecco il codice demo usando la classe precedente:
# DEMO
if __name__ == '__main__':
mouse = Mouse()
if sys.platform == "darwin":
print("Current mouse position: %d:%d" % mouse.position())
print("Moving to 100:100...");
mouse.move(100, 100)
print("Clicking 200:200 position with using the right button...");
mouse.click_pos(200, 200, mouse.RIGHT)
elif sys.platform == "win32":
print("Error: Platform not supported!")
È possibile combinare entrambi i blocchi di codice in un unico file, autorizzare l'esecuzione ed eseguirlo come script di shell.
Il modo più semplice? Compila questo App Cocoa e passagli i movimenti del mouse.
Ecco il codice:
// File:
// click.m
//
// Compile with:
// gcc -o click click.m -framework ApplicationServices -framework Foundation
//
// Usage:
// ./click -x pixels -y pixels
// At the given coordinates it will click and release.
#import <Foundation/Foundation.h>
#import <ApplicationServices/ApplicationServices.h>
int main(int argc, char **argv) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSUserDefaults *args = [NSUserDefaults standardUserDefaults];
// grabs command line arguments -x and -y
//
int x = [args integerForKey:@"x"];
int y = [args integerForKey:@"y"];
// The data structure CGPoint represents a point in a two-dimensional
// coordinate system. Here, X and Y distance from upper left, in pixels.
//
CGPoint pt;
pt.x = x;
pt.y = y;
// https://stackoverflow.com/questions/1483567/cgpostmouseevent-replacement-on-snow-leopard
CGEventRef theEvent = CGEventCreateMouseEvent(NULL, kCGEventLeftMouseDown, pt, kCGMouseButtonLeft);
CGEventSetType(theEvent, kCGEventLeftMouseDown);
CGEventPost(kCGHIDEventTap, theEvent);
CFRelease(theEvent);
[pool release];
return 0;
}
App chiamata click che richiama CGPostMouseEvent dal file di intestazione CGRemoteOperation.h. Prende le coordinate come argomenti della riga di comando, sposta il mouse in quella posizione, quindi fa clic e rilascia il pulsante del mouse.
Salva il codice sopra come click.m, apri Terminale e passa alla cartella in cui hai salvato la fonte. Quindi compilare il programma digitando
gcc -o click click.m -framework ApplicationServices -framework Foundation
. Non lasciarti intimidire dal bisogno di compilare questo dato che ci sono più commenti che codice. È un programma molto breve che fa un semplice compito.
Un altro modo? Importa pyobjc per accedere ad alcuni framework OSX e accedere al mouse in quel modo. (vedi il codice dal primo esempio per idee).