11

Python で記述されたアプリで、Mac のグローバル マウス イベント (アプリにバインドされていない) をリッスンする必要があります。

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();

しかし、これは永久に実行され、マウスイベントに応答しません。何が問題なのですか?

4

3 に答える 3

3

CGEventTapCreateの4番目のパラメーターは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)
于 2010-12-19T04:17:04.113 に答える
1

CGEventTapCreateのドキュメント( http://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate ) には、root になる必要があると記載されています。 kCGHIDEventTap を使用します。スクリプトをルートとして実行していますか? (sudo はこれを行う 1 つの方法です)

そうである場合は、tap が None かどうかも確認する必要があります。それは問題を絞り込むのに役立ちます。ドキュメントには、 CGEventTapCreateが NULL を返す可能性のあるエラー条件がいくつか記載されています。これは、Python では None として反映されるはずです。

于 2010-03-07T03:26:59.730 に答える
-1

まず、CGEventTapCreateCGEventTapCreateForPSNが呼び出されると、一部のメモリ リークが発生します。これは、メモリ管理の問題を回避するために必要です。したがって、これらの関数を呼び出さないことをお勧めします。少なくとも数回は呼び出します。

さて、マウスイベントは次のように機能します:

evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft)
self.failUnlessIsInstance(evt, CGEventRef)
于 2010-02-25T20:46:49.477 に答える