我需要在用Mac编写的应用程序中监听Mac上的全局鼠标事件(未绑定到应用程序)。
我正在使用PyObjC,但我无法弄清楚如何做到这一点。简单的ObjC示例或其他Python技术也很受欢迎。
到目前为止我的代码:
from Quartz import *
def MyFunction(proxy, type, event):
print event
CGEventTapCreate(kCGHIDEventTap, kCGTailAppendEventTap, kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction)
==分段错误
我知道我需要稍后将其添加到事件源中,但我需要先使用它。
[更新]
使用PyObjC表单Macports解决了段错误,所以现在我写了这个:
from Quartz import *
def MyFunction(p, t, e, c):
print e
tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction, None)
runLoopSource = CFMachPortCreateRunLoopSource(None, tap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
CGEventTapEnable(tap, True);
CFRunLoopRun();
但这只是永远运行而且不响应鼠标事件,出了什么问题?
答案 0 :(得分:2)
CGEventTapCreate的第四个参数是CGEventMask eventsOfInterest
,你给它kCGEventLeftMouseDown
这是一个_CGEventType
类型的枚举。您需要翻转位掩码中的相应位,而不是整数常量。您可以使用CGEventMaskBit
所以不要这样:
tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction, None)
我们可以这样做:
tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
kCGEventTapOptionListenOnly, CGEventMaskBit(kCGEventLeftMouseDown),
MyFunction, None)
或等效地:
tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
kCGEventTapOptionListenOnly, (1 << kCGEventLeftMouseDown),
MyFunction, None)
答案 1 :(得分:1)
CGEventTapCreate (http://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate)的文档说您需要是root才能使用kCGHIDEventTap。您是否以root身份运行脚本? (sudo是这样做的一种方式)
如果你是,你还应该检查tap是否为None;这将有助于缩小问题范围。文档中列出的几个错误条件可能导致 CGEventTapCreate 返回NULL,这应该在Python中反映为None。
答案 2 :(得分:-1)
首先, CGEventTapCreate 和 CGEventTapCreateForPSN 会泄漏一些内存 叫做。这是避免内存管理问题所必需的。因此 建议不要调用这些函数,至少称它们为少数 时间。
现在,鼠标事件的工作原理如下:
evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft)
self.failUnlessIsInstance(evt, CGEventRef)