Мне нужно прослушивать глобальные события мыши (не привязанные к приложению) на моем Mac в приложении, написанном на Python.
Я использую 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();
Но это просто работает вечно и не реагирует на события мыши, что не так?
Ответ 1 · рейтинг 3 · Felix Fung
Четвертый параметр 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)
Ответ 3 · рейтинг -1 · Todd Moses
Во-первых, при вызове CGEventTapCreate и CGEventTapCreateForPSN происходит утечка памяти. Это нужно, чтобы избежать проблем с управлением памятью. Поэтому рекомендуется не вызывать эти функции, по крайней мере вызывать их небольшое количество раз.
Теперь событие мыши работает примерно так:
evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft)
self.failUnlessIsInstance(evt, CGEventRef)