37

在 OS X 上使用 Python 移动鼠标(并可能单击)的最简单方法是什么?

这只是为了快速原型设计,它不一定是优雅的。

4

11 回答 11

32

试试这个页面的代码。它定义了几个函数mousemovemouseclick,它们与 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 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."
于 2011-11-20T15:48:30.543 回答
20

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)
于 2017-03-12T15:44:11.297 回答
15

最简单的方法是使用 PyAutoGUI。

安装:

pip install pyautogui

例子:

  • 获取鼠标位置:

    >>> pyautogui.position()
    (187, 567)
    
  • 将鼠标移动到特定位置:

    >>> pyautogui.moveTo(100,200)
    
  • 要触发鼠标单击:

    >>> pyautogui.click()
    

更多细节:PyAutoGUI

于 2018-03-27T13:29:22.877 回答
11

试试这个代码:

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

于 2009-03-19T23:15:07.620 回答
9

我翻遍了 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 绑定!

于 2008-11-11T16:10:11.010 回答
8

当我想这样做时,我安装了Jython并使用了java.awt.Robot该类。如果您需要制作 CPython 脚本,这显然不合适,但是当您可以灵活选择任何东西时,它是一个不错的跨平台解决方案。

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)
于 2008-11-11T16:23:20.830 回答
2

最好的办法是使用AutoPy 包。它使用起来非常简单,并且可以跨平台启动。

要将光标移动到位置 (200,200):

import autopy
autopy.mouse.move(200,200)
于 2013-07-10T18:49:19.417 回答
1

来自geekorgy.com的 python 脚本很棒,除了我安装了更新版本的 python 后遇到了一些障碍。所以这里有一些提示给其他可能正在寻找解决方案的人。

如果您在 Mac OS 10.6 上安装了 Python 2.7,您有几个选项可以让 Python 从 Quartz.CoreGraphics 导入:

A)在终端中,键入python2.6而不是就python在脚本路径之前

B)您可以通过执行以下操作来安装 PyObjC :

  1. 从http://pypi.python.org/pypi/setuptools安装 easy_install
  2. 在终端中,键入which python并复制路径2.7
  3. 然后输入easy_install –-prefix /Path/To/Python/Version pyobjc==2.3

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

  4. import objc在顶部的脚本类型内
  5. 如果第一次 easy_install 不起作用,您可能需要先安装核心:

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

C)您可以将您的 python 路径重置为原始 Mac OS python:

  • 在终端中,键入:defaults write com.apple.versioner.python Version 2.6

***另外,一种快速找出屏幕上 (x,y) 坐标的方法:

  1. 按下Command+Shift+4(屏幕抓取选择)
  2. 然后光标显示坐标
  3. 然后按 Esc 退出它。
于 2012-05-22T05:51:10.757 回答
0

最简单的方法?编译这个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;


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

名为 click 的应用程序从 CGRemoteOperation.h 头文件调用 CGPostMouseEvent。它将坐标作为命令行参数,将鼠标移动到该位置,然后单击并释放鼠标按钮。

将以上代码另存为click.m,打开终端,切换到你保存源码的文件夹。然后通过键入来编译程序gcc -o click click.m -framework ApplicationServices -framework Foundation。不要被需要编译它吓倒,因为注释多于代码。这是一个非常短的程序,可以完成一项简单的任务。


其他方式?导入pyobjc以访问某些 OSX 框架并以这种方式访问​​鼠标。(有关想法,请参见第一个示例中的代码)。

于 2008-11-15T03:48:07.897 回答
0

从 Quartz 库中使用CoreGraphics,例如:

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

资料来源:Geekorgy 页面上的 Tony 评论

于 2017-05-26T13:25:29.330 回答
0

这是使用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.pymouseUtils.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!")

您可以将两个代码块合并到一个文件中,授予执行权限并将其作为 shell 脚本运行。

于 2017-05-28T18:26:22.463 回答