Pregunta

¿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 la creación rápida de prototipos, no tiene que ser elegante.

¿Fue útil?

Solución 3

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

¡Ahora para escribir enlaces de Python!

Otros consejos

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

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

Cuando quería hacerlo, instalé Jython y utilicé el java.awt.Robot clase. Si necesita crear un script de 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 pynput parece la mejor biblioteca mantenida actualmente. Le 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 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

El script de Python de geekorgy.com es genial, excepto que me encontré con algunos inconvenientes desde que instalé una versión más nueva de python. Así que aquí hay algunos consejos para otros que puedan estar buscando una solución.

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

A) En la terminal, escriba python2.6 en lugar de solo python antes de la ruta a la guión

B) Puede instalar PyObjC haciendo lo siguiente:

  1. Instale easy_install desde http://pypi.python.org/pypi/setuptools
  2. En la terminal, escriba which python y copie la ruta a través de 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 primero necesite instalar 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 al Python original de Mac OS:

  • En el terminal, escriba: valores predeterminados write com.apple.versioner.python Version 2.6

*** Además, 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 presiona Esc para salir de él.

Su mejor opción es utilizar 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 de la biblioteca 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: Comentario de Tony en la página de Geekorgy .

Aquí está el ejemplo completo usando la biblioteca 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 < code> mouseUtils.py .

Aquí está el código de demostración usando 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.

¿La forma más fácil? Compile this Aplicación de cacao y pásalo con los movimientos del 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://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 CGPostMouseEvent desde el archivo de encabezado CGRemoteOperation.h. Toma las coordenadas como argumentos de 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 Terminal y cambie a la carpeta donde guardó la 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.


¿Otra forma? Importe pyobjc para acceder a parte del marco OSX y acceder al mouse de esa manera. (vea el código del primer ejemplo para ideas).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top