¿Cómo controlar el mouse en Mac usando Python?

¿Cuál sería la forma más fácil de mover el mouse (y posiblemente hacer clic) utilizando Python en OS X?

Esto es solo para la creación rápida de prototipos, no tiene que ser elegante.

Prueba el código en esta página . Define un par de funciones, mousemove y mouseclick , que se enganchan en la integración de Apple entre Python y las bibliotecas de cuarzo de la plataforma.

Este código funciona en 10.6, y lo estoy usando en 10.7. Lo bueno de este código es que genera eventos de mouse, que algunas soluciones no lo hacen. Lo uso para controlar BBC iPlayer enviando eventos del mouse a posiciones de botón conocidas en su Flash player (lo sé muy frágil). Los eventos de movimiento del mouse, en particular, son necesarios, de lo contrario, Flash Player nunca oculta el cursor del mouse. Funciones como CGWarpMouseCursorPosition no harán esto.

 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); 

Aquí está el ejemplo del código de la página anterior:

 ############################################################## # 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." 

Solo prueba este código:

 #!/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) 

Funciona en OSX Leopard 10.5.6.

Busqué en el código fuente de Synergy para encontrar la llamada que genera eventos del mouse:

 #include  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; } 

Ahora para escribir enlaces de Python!

Cuando quise hacerlo, instalé Jython y usé la clase java.awt.Robot . Si necesita hacer un script CPython, esto obviamente no es adecuado, pero cuando tiene la flexibilidad de elegir cualquier cosa, es una buena solución multiplataforma.

 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 biblioteca pynput parece ser la mejor biblioteca actualmente mantenida. Te permite controlar y monitorear dispositivos de entrada.

Aquí está el ejemplo para controlar el 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) 

La forma más fácil es usar PyAutoGUI.
Ejemplo:

  • Para obtener la posición del ratón:

     >>> pyautogui.position() (187, 567) 
  • Para mover el mouse a una posición específica:

     >>> pyautogui.moveTo(100,200) 
  • Para activar un clic del ratón:

     >>> pyautogui.click() 

Más detalle: PyAutoGUI

El script de python de geekorgy.com es excelente, excepto que tuve algunos inconvenientes desde que instalé una versión más nueva de python. Así que aquí hay algunos consejos para otros que pueden estar buscando una solución.

Si instaló Python 2.7 en su Mac OS 10.6, tiene algunas opciones para hacer que Python importe desde Quartz.CoreGraphics:

A) En la terminal, escriba python2.6 lugar de solo python antes de la ruta al script

B) Puedes instalar PyObjC haciendo lo siguiente:

  1. Instale easy_install desde http://pypi.python.org/pypi/setuptools
  2. En el terminal, escriba which python y copie la ruta hasta 2.7
  3. Luego escriba easy_install –-prefix /Path/To/Python/Version pyobjc==2.3

    **es decir. easy_install –-prefix /Library/Frameworks/Python.framework/Versions/2.7 pyobjc==2.3

  4. Dentro del tipo de script, import objc en la parte superior
  5. Si easy_install no funciona la primera vez, es posible que deba instalar el núcleo primero:

    **es decir. easy_install --prefix /Library/Frameworks/Python.framework/Versions/2.7 pyobjc-core==2.3

C) Puedes restablecer tu ruta de python a la de python original de Mac OS:

  • En el terminal, escriba: los defaults write com.apple.versioner.python Version 2.6

*** También, una forma rápida de averiguar las coordenadas (x, y) en la pantalla:

  1. Presione Command+Shift+4 (selección de captura de pantalla)
  2. El cursor muestra las coordenadas.
  3. Luego pulsa Esc para salir de ella.

Su mejor apuesta es usar el paquete AutoPy . Es extremadamente simple de usar y multiplataforma para arrancar.

Para mover el cursor a la posición (200,200):

 import autopy autopy.mouse.move(200,200) 

Use CoreGraphics de la biblioteca de cuarzo, por ejemplo:

 from Quartz.CoreGraphics import CGEventCreate from Quartz.CoreGraphics import CGEventGetLocation ourEvent = CGEventCreate(None); currentpos = CGEventGetLocation(ourEvent); mousemove(currentpos.x,currentpos.y) 

Fuente: Tony comenta en la página de Geekorgy .

Aquí está el ejemplo completo usando la biblioteca de 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) 

El código anterior se basa en estos archivos originales: Mouse.py mouseUtils.py .

Aquí está el código de demostración utilizando la clase anterior:

 # 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!") 

Puede combinar ambos bloques de código en un archivo, dar permiso de ejecución y ejecutarlo como un script de shell.

¿La forma más fácil? Comstack esta aplicación Cocoa y pásala con los movimientos de tu ratón.

Aquí está el código:

 // 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  #import  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; } 

Aplicación llamada clic que invoca a CGPostMouseEvent desde el archivo de encabezado CGRemoteOperation.h. Toma las coordenadas como argumentos de la línea de comando, mueve el mouse a esa posición, luego hace clic y suelta el botón del mouse.

Guarde el código anterior como click.m, abra el Terminal y cambie a la carpeta donde guardó la fuente. Luego compile el progtwig escribiendo gcc -o click click.m -framework ApplicationServices -framework Foundation . No se deje intimidar por la necesidad de comstackr esto, ya que hay más comentarios que código. Es un progtwig muy corto que hace una tarea simple.


¿De otra manera? Importe pyobjc para acceder a algunos de los marcos OSX y acceder al mouse de esa manera. (vea el código del primer ejemplo para ideas).