Я должен прислушаться к глобальным событиям от нажатия мыши (не связанный с приложением) на моем Mac в приложении, записанном в Python.
Я использую PyObjC, но я не могу выяснить, как сделать это. Простые примеры ObjC или другие методы Python также ценятся.
Мой код до сих пор:
from Quartz import *
def MyFunction(proxy, type, event):
print event
CGEventTapCreate(kCGHIDEventTap, kCGTailAppendEventTap, kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction)
== Отказ сегментации
Я знаю, что должен добавить его к источнику события позже, но я должен получить эту работу сначала.
[обновление]
Используя форму PyObjC Macports решил segfault, поэтому теперь я записал это:
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();
Но это просто работает навсегда и не отвечает на события от нажатия мыши, что не так?
Во-первых, CGEventTapCreate и CGEventTapCreateForPSN дают утечку памяти при их вызове . Это необходимо, чтобы избежать проблем с управлением памятью. Поэтому рекомендуется не вызывать эти функции, по крайней мере вызывать их небольшое количество раз.
Теперь событие мыши работает примерно так:
evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft)
self.failUnlessIsInstance(evt, CGEventRef)
В документации для CGEventTapCreate (http://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate) говорится, что для использования kCGHIDEventTap необходимо быть root. Вы запускаете свой скрипт от имени root? (sudo - один из способов сделать это)
Если да, то вам также следует проверить, является ли tap значением None; это поможет сузить проблему. В документации перечислены несколько условий ошибки, которые могут привести к тому, что CGEventTapCreate возвращает NULL, что в Python должно отражаться как None.