11

我需要在用 Python 编写的应用程序中侦听 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();

但这只是永远运行并且不响应鼠标事件,这是怎么回事?

4

3 回答 3

3

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)
于 2010-12-19T04:17:04.113 回答
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。

于 2010-03-07T03:26:59.730 回答
-1

首先,CGEventTapCreateCGEventTapCreateForPSN在调用时会泄漏一些内存。这是避免内存管理问题所必需的。因此建议不要调用这些函数,至少调用它们的次数很少。

现在,鼠标事件的工作方式如下:

evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft)
self.failUnlessIsInstance(evt, CGEventRef)
于 2010-02-25T20:46:49.477 回答