2010-02-25 73 views
9

我需要在用Python编写的应用程序中监听我的Mac上的全局鼠标事件(未绑定到应用程序)。如何在Mac上监听Python中的鼠标事件?

我使用PyObjC,但我无法弄清楚如何去做。 Plain 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(); 

但这只是一直运行,不响应鼠标事件,有什么不好?

回答

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) 
+0

这应该是正确的答案 – 2011-03-10 10:59:20

-1

首先,CGEventTapCreateCGEventTapCreateForPSN泄露一些内存,他们 被调用时。这是避免内存管理问题所必需的。因此 建议不要调用这些函数,至少称它们为小数字 的次数。现在

,鼠标事件的工作原理是这样的:

evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft) 
self.failUnlessIsInstance(evt, CGEventRef) 
+1

我不想送事件,我想听他们。 CGEventCreateMouseEvent用于创建事件,而不是事件点击。 – Pepijn 2010-02-25 21:46:04

+0

对不起。我搞砸了给你错误的代码示例。 – 2010-02-25 21:48:29

+1

还有另一种我以为我给你的Tap Event的方法。 – 2010-02-25 21:49:00

1

CGEventTapCreatehttp://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate)文档说,你需要root权限才能使用kCGHIDEventTap。你是否以root身份运行你的脚本? (sudo是这样做的一种方法)

如果你是,你也应该检查点击是否为无;这将有助于缩小问题的范围。在文档中列出的几种错误情况可能导致CGEventTapCreate返回NULL,这应在Python中反映为None。

+0

Sudo或不会产生影响,tap和runLoopSource都包含某些内容。是否有替代kCGHIDEventTap?我注意到CFRunLoopRunInMode(kCFRunLoopDefaultMode,20,False)会运行20秒,但立即提供True结束,但仍不会从MyFunction输出。 – Pepijn 2010-03-07 15:20:24

+0

这可能与将CGEventRef字符串化并试图进行打印有关吗?也许你可以尝试在MyFunction中打印一个常量字符串来确保。除此之外,我不知道。 – 2010-03-07 23:08:14

+0

我试图打印'嗨',但那也没有帮助。难道这个函数被调用的地方stdout设置不同? – Pepijn 2010-03-08 11:37:30