2010-02-25 156 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