Как я могу прослушать событие мыши в Python на Mac? - PullRequest
9 голосов
/ 25 февраля 2010

Мне нужно прослушивать глобальные события мыши (не связанные с приложением) на моем 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();

Но это работает вечно и не реагирует на события мыши, что не так?

Ответы [ 3 ]

2 голосов
/ 19 декабря 2010

Четвертый параметр 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)
1 голос
/ 07 марта 2010

Документация для CGEventTapCreate (http://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate) говорит, что вам нужно быть пользователем root, чтобы использовать kCGHIDEventTap. Вы запускаете свой скрипт как root? (Sudo - один из способов сделать это)

Если да, вы должны также проверить, является ли нажатие «Нет»; это поможет сузить проблему. В документации перечислено несколько состояний ошибки, которые могут привести к тому, что CGEventTapCreate вернет NULL, что должно быть отражено как None в Python.

0 голосов
/ 25 февраля 2010

Во-первых, CGEventTapCreate и CGEventTapCreateForPSN вызывают утечку памяти называются. Это необходимо, чтобы избежать проблем с управлением памятью. Поэтому желательно не вызывать эти функции, хотя бы назвать их небольшим числом раз.

Теперь событие мыши работает примерно так:

evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft)
self.failUnlessIsInstance(evt, CGEventRef)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...