如何在 Mac 上的 Python 中监听鼠标事件?

发布于 2024-08-23 04:11:31 字数 917 浏览 10 评论 0原文

我需要在我的 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();

但这只是永远运行并且不响应鼠标事件,出了什么问题?

I need to listen for global mouse events(not bound to an app) on my Mac in an app written in Python.

I'm using PyObjC, but I can't figure out how to do it. Plain ObjC examples or other Python techniques also appreciated.

My code so far:

from Quartz import *
def MyFunction(proxy, type, event):
    print event

CGEventTapCreate(kCGHIDEventTap, kCGTailAppendEventTap, kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction)

== Segmentation fault

I know I need to add it to an event source later on, but I need to get this working first.

[update]

Using PyObjC form Macports solved the segfault, so now I wrote this:

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

But this just runs forever and does not respond to mouse events, what is wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白况 2024-08-30 04:11:31

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)

The fourth parameter of CGEventTapCreate is CGEventMask eventsOfInterest, and you gave it kCGEventLeftMouseDown which is an enum of type _CGEventType. Instead of the integer constant, you need to flip the appropriate bit in the bitmask. You can do this using CGEventMaskBit

So instead of this:

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
    kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction, None)

We can do this:

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
    kCGEventTapOptionListenOnly, CGEventMaskBit(kCGEventLeftMouseDown),
    MyFunction, None)

or equivalently:

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
    kCGEventTapOptionListenOnly, (1 << kCGEventLeftMouseDown),
    MyFunction, None)
荭秂 2024-08-30 04:11:31

CGEventTapCreate 的文档 (http://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate< /a>) 表示您需要 root 才能使用 kCGHIDEventTap。您是否以 root 身份运行脚本? (sudo 是执行此操作的一种方法)

如果是,您还应该检查 tap 是否为 None;这将有助于缩小问题范围。文档中列出了几种可能导致 CGEventTapCreate 返回 NULL 的错误条件,这在 Python 中应反映为 None。

The documentation for CGEventTapCreate (http://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate) says that you need to be root to use kCGHIDEventTap. Are you running your script as root? (sudo is one way to do this)

If you are, you should also check whether tap is None; that will help narrow down the problem. There are several error conditions listed in the documentation that can cause CGEventTapCreate to return NULL, which should be reflected as None in Python.

〃安静 2024-08-30 04:11:31

首先,CGEventTapCreateCGEventTapCreateForPSN在执行时会泄漏一些内存。
被称为。这是避免内存管理问题所必需的。因此是
建议不要调用这些函数,至少少调用它们
次。

现在,鼠标事件的工作原理如下:

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

First, CGEventTapCreate and CGEventTapCreateForPSN leak some memory when they
are called. This is needed to avoid memory management problems. It is therefore
advisable not to call these functions, are at least call them a small number
of times.

Now, a mouse event works something like this:

evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft)
self.failUnlessIsInstance(evt, CGEventRef)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文