Question

Quel serait le moyen le plus simple de déplacer la souris (et éventuellement de cliquer) à l’aide de Python sous OS X?

Ceci est juste pour le prototypage rapide, il n'a pas besoin d'être élégant.

Était-ce utile?

La solution 3

J'ai creusé dans le code source de Synergy pour rechercher l'appel qui génère des événements de souris:

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

Maintenant, écrivez des liaisons Python!

Autres conseils

Essayez le code à cette page . Il définit deux fonctions, mousemove et mouseclick , qui s’intègrent à l’intégration d’Apple entre Python et les bibliothèques Quartz de la plate-forme.

Ce code fonctionne sur 10.6 et je l’utilise sur 10.7. L'avantage de ce code est qu'il génère des événements de souris, ce que certaines solutions ne permettent pas. Je l'utilise pour contrôler BBC iPlayer en envoyant des événements de souris à des positions de bouton connues dans leur lecteur Flash (très fragile, je le sais). Les événements de déplacement de la souris, en particulier, sont requis, sinon le lecteur Flash ne cache jamais le curseur de la souris. Des fonctions comme CGWarpMouseCursorPosition ne le feront pas.

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

Voici l'exemple de code de la page ci-dessus:

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

Essayez ce code:

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

cela fonctionne dans OSX Leopard 10.5.6

Quand j'ai voulu le faire, j'ai installé Jython et utilisé le java.awt.Robot classe. Si vous avez besoin de créer un script CPython, cela ne convient évidemment pas, mais lorsque vous avez la possibilité de choisir ce que vous voulez, vous obtenez une belle solution multiplate-forme.

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 bibliothèque pynput semble être la meilleure des bibliothèques actuellement gérées. Il vous permet de contrôler et de surveiller les périphériques d’entrée.

Voici l'exemple de contrôle de la souris:

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)

Le moyen le plus simple consiste à utiliser PyAutoGUI.
Exemple:

  • Pour obtenir la position de la souris:

    >>> pyautogui.position()
    (187, 567)
    
  • Pour déplacer la souris à une position spécifique:

    >>> pyautogui.moveTo(100,200)
    
  • Pour déclencher un clic de souris:

    >>> pyautogui.click()
    

Plus de détails: PyAutoGUI

Le script python de geekorgy.com est génial, sauf que j'ai rencontré quelques problèmes depuis que j'ai installé une version plus récente de python. Alors, voici quelques conseils pour ceux qui cherchent peut-être une solution.

Si vous avez installé Python 2.7 sur votre Mac OS 10.6, vous disposez de quelques options pour importer du python à partir de Quartz.CoreGraphics:

A) Dans le terminal, tapez python2.6 au lieu de python avant le chemin d'accès au script

B) Vous pouvez installer PyObjC en procédant comme suit:

  1. Installez easy_install à partir de http://pypi.python.org/pypi/setuptools
  2. Dans le terminal, tapez quel python et copiez le chemin jusqu'à 2.7
  3. Tapez ensuite easy_install & # 8211; -prefix / Path / To / Python / Version pyobjc == 2.3

    ** C'est à dire. easy_install & # 8211; -prefix /Library/Frameworks/Python.framework/Versions/2.7 pyobjc == 2.3

  4. Dans le type de script import objc en haut
  5. Si easy_install ne fonctionne pas la première fois, vous devrez peut-être installer le noyau en premier:

    ** C'est à dire. easy_install --prefix /Library/Frameworks/Python.framework/Versions/2.7 pyobjc-core == 2.3

C) Vous pouvez réinitialiser votre chemin d'accès python au python Mac OS d'origine:

  • Dans le terminal, tapez: par défaut write com.apple.versioner.python Version 2.6

*** En outre, un moyen rapide de connaître les coordonnées (x, y) à l'écran:

  1. Appuyez sur Commande + Maj + 4 (sélection de capture d'écran)
  2. Le curseur affiche alors les coordonnées
  3. Appuyez ensuite sur Echap pour en sortir.

La meilleure solution consiste à utiliser le package AutoPy . C'est extrêmement simple à utiliser et multi-plateforme pour démarrer.

Pour déplacer le curseur sur la position (200 200):

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

Utilisez CoreGraphics dans la bibliothèque Quartz, par exemple:

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

Source: Commentaire de Tony sur la page Geekorgy .

Voici l'exemple complet utilisant la bibliothèque 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)

Le code ci-dessus est basé sur ces fichiers d'origine: Mouse.py < code> mouseUtils.py .

Voici le code de démonstration utilisant la classe ci-dessus:

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

Vous pouvez combiner les deux blocs de code dans un seul fichier, donner une autorisation d'exécution et l'exécuter en tant que script shell.

Le moyen le plus simple? Compilez this . Cocoa app et transmettez les mouvements de votre souris.

Voici le code:

// 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 appelé click qui appelle CGPostMouseEvent à partir du fichier d'en-tête CGRemoteOperation.h. Il prend les coordonnées comme arguments de ligne de commande, déplace la souris à cette position, puis clique et relâche le bouton de la souris.

     

Enregistrez le code ci-dessus sous le nom click.m, ouvrez Terminal et accédez au dossier où vous avez enregistré la source. Puis compilez le programme en tapant gcc -o cliquez sur click.m -framework ApplicationServices -framework Foundation . Ne soyez pas intimidé par la nécessité de compiler ceci car il y a plus de commentaires que de code. C'est un programme très court qui effectue une tâche simple.

Une autre façon? Importez pyobjc pour accéder à une partie du framework OSX et à la souris de cette façon. (voir le code du premier exemple pour des idées).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top