Подтвердить что ты не робот

Как управлять мышью на Mac с помощью Python?

Каким будет самый простой способ перемещения мыши (и, возможно, щелчка) с помощью Python на OS X?

Это просто для быстрого прототипирования, оно не должно быть элегантным.

4b9b3361

Ответ 1

Я выкопал исходный код Synergy, чтобы найти вызов, который генерирует события мыши:

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

Теперь, чтобы написать привязки Python!

Ответ 2

Попробуйте код эту страницу. Он определяет пару функций mousemove и mouseclick, которые подключаются к интеграции Apple между Python и библиотеками Quartz платформы.

Этот код работает на 10.6, и я использую его на 10.7. Самое приятное в этом коде - это то, что он генерирует события мыши, которых нет в некоторых решениях. Я использую его для управления BBC iPlayer, отправляя события мыши на известные позиции кнопок в своем Flash-проигрывателе (очень хрупкие, которых я знаю). События перемещения мыши, в частности, требуются, поскольку в противном случае Flash-плеер никогда не скрывает курсор мыши. Такие функции, как CGWarpMouseCursorPosition, не будут выполняться.

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

Вот пример кода с предыдущей страницы:

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

Ответ 3

Просто попробуйте этот код:

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

он работает в OSX leopard 10.5.6

Ответ 4

Когда я захотел сделать это, я установил Jython и использовал java.awt.Robot. Если вам нужно сделать CPython script, это явно не подходит, но когда вы можете выбрать что угодно, это хорошее кросс-платформенное решение.

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)

Ответ 5

Библиотека pynput кажется лучшей в настоящее время поддерживаемой библиотекой. Он позволяет вам контролировать и контролировать устройства ввода.

Вот пример управления мышью:

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)

Ответ 6

python script из geekorgy.com отлично, за исключением того, что я столкнулся с несколькими корягами, так как я установил более новую версию python. Итак, вот несколько советов для других, которые могут искать решение.

Если вы установили Python 2.7 на Mac OS 10.6, у вас есть несколько вариантов для импорта python из Quartz.CoreGraphics:

A) В терминале введите python2.6 вместо всего python перед тем, как путь к script

B) Вы можете установить PyObjC, выполнив следующие действия:

  • Установить easy_install из http://pypi.python.org/pypi/setuptools
  • В терминале введите which python и скопируйте путь до 2.7
  • Затем введите easy_install –-prefix /Path/To/Python/Version pyobjc==2.3

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

  • Внутри script тип import objc вверху
  • Если easy_install не работает в первый раз, вам может понадобиться сначала установить ядро:

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

C) Вы можете reset ваш путь python к исходному питону Mac OS:

  • В терминале введите: defaults write com.apple.versioner.python Version 2.6

*** Также, быстрый способ узнать координаты (x, y) на экране:

  • Нажмите Command+Shift+4 (выбор захвата экрана)
  • Затем курсор отображает координаты
  • Затем нажмите Esc, чтобы выйти из него.

Ответ 7

Лучше всего использовать пакет AutoPy. Он чрезвычайно прост в использовании и кросс-платформенный для загрузки.

Чтобы переместить курсор в позицию (200 200):

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

Ответ 8

Самый простой способ? Скомпилируйте это Cocoa приложение и передайте его движениям мыши.

Вот код:

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


  // This is where the magic happens.  See CGRemoteOperation.h for details.
  //
  // CGPostMouseEvent( CGPoint        mouseCursorPosition,
  //                   boolean_t      updateMouseCursorPosition,
  //                   CGButtonCount  buttonCount,
  //                   boolean_t      mouseButtonDown, ... )
  //
  // So, we feed coordinates to CGPostMouseEvent, put the mouse there,
  // then click and release.
  //
  CGPostMouseEvent( pt, 1, 1, 1 );
  CGPostMouseEvent( pt, 1, 1, 0 );


  pool release;
  return 0;

Приложение называется кликом, который вызывает CGPostMouseEvent из файла заголовка CGRemoteOperation.h. Он принимает координаты как аргументы командной строки, перемещает мышь в эту позицию, затем щелкает и отпускает кнопку мыши.

Сохраните приведенный выше код как click.m, откройте Terminal и перейдите в папку, в которой вы сохранили источник. Затем скомпилируйте программу, набрав gcc -o click click.m -framework ApplicationServices -framework Foundation. Не пугайтесь, если вам нужно скомпилировать это, поскольку есть больше комментариев, чем код. Это очень короткая программа, которая выполняет одну простую задачу.


Другой способ? Импортируйте pyobjc для доступа к некоторой платформе OSX и доступа к этой мыши. (см. код из первого примера для идей).

Ответ 9

Используйте CoreGraphics из библиотеки Quartz, например:

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

Источник: Комментарий Тони на странице Geekorgy.

Ответ 10

Вот полный пример с использованием библиотеки 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)

Выше код основан на этих исходных файлах: Mouse.py mouseUtils.py.

Вот демонстрационный код с использованием вышеуказанного класса:

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

Вы можете объединить оба блока кода в один файл, предоставить разрешение на выполнение и запустить его как оболочку script.