Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как я могу прослушать событие мыши в Python на Mac?

Автор вопроса: PepijnОтветов: 3

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

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

pythonpyobjcobjective-cmouseevent

Ответы

Ответ 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)

Ответ 2 · рейтинг 1 · Scott Wolchok

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

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

Ответ 3 · рейтинг -1 · Todd Moses

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

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы