pynput python macos mouse

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



python keyboard (11)

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

Esto es solo para prototipos rápidos, no tiene que ser elegante.


¿La forma más fácil? Compila this aplicación Cocoa y pásale los movimientos de tu mouse.

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 <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://.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 CGPostMouseEvent desde el archivo de encabezado CGRemoteOperation.h. Toma coordenadas como argumentos de línea de comandos, 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 Terminal y cambie a la carpeta donde guardó el código fuente. Luego, compile el programa escribiendo gcc -o click click.m -framework ApplicationServices -framework Foundation . No se deje intimidar por la necesidad de compilar esto ya que hay más comentarios que código. Es un programa muy corto que realiza una tarea simple.

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


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 que usa 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, otorgar permiso de ejecución y ejecutarlo como un script de shell.


Busqué en el código fuente de Synergy para encontrar la llamada que genera eventos de 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; }

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


El script de python de geekorgy.com es excelente, salvo que encontré algunos inconvenientes desde que instalé una versión más nueva de python. 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 que Python pueda importar desde Quartz.CoreGraphics:

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

B) Puede instalar PyObjC haciendo lo siguiente:

  1. Instala easy_install desde http://pypi.python.org/pypi/setuptools
  2. En la terminal, escribe which python y copia 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 script escriba import objc en la parte superior
  5. Si easy_install no funciona la primera vez, es posible que deba instalar primero el núcleo:

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

C) Puede restablecer su ruta de Python a la python original de Mac OS:

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

*** También, una forma rápida de descubrir 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 presiona Esc para salir de ella.

La biblioteca pynput parece ser la mejor biblioteca mantenida actualmente. Le permite controlar y controlar los 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 mouse:

    >>> pyautogui.position() (187, 567)

  • Para mover el mouse a una posición específica:

    >>> pyautogui.moveTo(100,200)

  • Para activar un clic del mouse:

    >>> pyautogui.click()

Más detalles: PyAutoGUI


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


Su mejor opción 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)


Utilice CoreGraphics desde la biblioteca de Quartz, 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 .


Prueba el código en esta página . Define un par de funciones, mousemove y mouseclick , que mouseclick la integración de Apple entre Python y las bibliotecas de Quartz 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 uso para controlar BBC iPlayer enviando eventos de mouse a posiciones de botón conocidas en su reproductor Flash (muy frágil, lo sé). Los eventos de movimiento del mouse, en particular, son necesarios ya que de lo contrario, el reproductor de Flash 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 de 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."