如何使用Python在Mac中控制鼠标?
在OS X上使用Python移动鼠标(也可能是点击)最简单的方法是什么?
这只是为了快速成型,它不一定非常优雅。
试试这个页面的代码。 它定义了一些函数, mousemove
和mouseclick
,它们embedded到了Python与平台的Quartz库之间的Apple集成中。
这个代码在10.6上工作,我在10.7上使用它。 关于这个代码的好处是它生成鼠标事件,而某些解决scheme则不能。 我使用它来控制BBC iPlayer,将鼠标事件发送到Flash播放器中已知的button位置(我知道非常脆弱)。 特别是鼠标移动事件是必需的,否则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."
试试这个代码:
#!/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豹10.5.6
我通过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绑定!
当我想要这样做时,我安装了Jython并使用了java.awt.Robot
类。 如果你需要制作一个CPython脚本,这显然是不合适的,但是当你select任何东西的时候,这是一个很好的跨平台解决scheme。
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)
pynput
库似乎是当前最好的库。 它允许您控制和监视input设备。
这里是控制鼠标的例子:
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)
从geekorgy.com的python脚本是伟大的,除了我碰到几个障碍,因为我安装了一个较新版本的python。 所以这里有一些提示给其他人可能正在寻找一个解决scheme。
如果您在Mac OS 10.6上安装了Python 2.7,则有几个选项可以从Quartz.CoreGraphics中导入python:
A)在terminal中, inputpython2.6
而不是python
脚本之前的path
B)您可以通过执行以下操作来安装PyObjC :
- 从http://pypi.python.org/pypi/setuptools安装easy_install
- 在terminal中,input
which python
并将path复制到2.7
-
然后input
easy_install –-prefix /Path/To/Python/Version pyobjc==2.3
**即。
easy_install –-prefix /Library/Frameworks/Python.framework/Versions/2.7 pyobjc==2.3
- 在脚本内部,在顶部
import objc
-
如果easy_install第一次无法正常工作,您可能需要先安装核心:
**即。
easy_install --prefix /Library/Frameworks/Python.framework/Versions/2.7 pyobjc-core==2.3
C)你可以重置你的Pythonpath到原始的Mac OS Python:
- 在terminal中input:
defaults write com.apple.versioner.python Version 2.6
***另外,快速找出屏幕上的(x,y)坐标:
- 按下
Command+Shift+4
(屏幕截图select) - 光标然后显示坐标
- 然后打Esc离开它。
你最好的select是使用AutoPy包 。 这是非常简单的使用,并跨平台启动。
将光标移动到位置(200,200):
import autopy autopy.mouse.move(200,200)
使用Quartz库中的CoreGraphics
,例如:
from Quartz.CoreGraphics import CGEventCreate from Quartz.CoreGraphics import CGEventGetLocation ourEvent = CGEventCreate(None); currentpos = CGEventGetLocation(ourEvent); mousemove(currentpos.x,currentpos.y)
来源: 托尼评论在Geekorgy页面 。
这是使用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!")
您可以将两个代码块组合到一个文件中,提供执行权限并将其作为shell脚本运行。
最简单的方法? 编译这个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;
从CGRemoteOperation.h头文件调用CGPostMouseEvent的名为click的App。 它将坐标作为命令行参数,将鼠标移动到该位置,然后单击并释放鼠标button。
将上面的代码保存为click.m,打开terminal,然后切换到保存源的文件夹。 然后通过input
gcc -o click click.m -framework ApplicationServices -framework Foundation
来编译程序gcc -o click click.m -framework ApplicationServices -framework Foundation
。 不要因为需要编译而感到恐惧,因为评论比代码更多。 这是一个非常简短的程序,完成一项简单的任务。
其他方式? 导入pyobjc访问一些OSX框架并以这种方式访问鼠标。 (请参阅第一个示例的代码)。