类似于OS X上的pyHook [英] Something like pyHook on OS X

查看:182
本文介绍了类似于OS X上的pyHook的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实际上正在使用 pyHook ,但是我也想为OS X编写程序. 如果有人知道这样的模块……我已经在互联网上寻找了一段时间,但没有任何实际意义.

->想法是能够在python应用程序外部记录击键.我的应用程序是一个社区统计信息构建器,因此也可以从OS X获得统计信息.

预先感谢;)

修改: PyHook:在python应用程序之外记录击键和其他内容 http://sourceforge.net/apps/mediawiki/pyhook/index.php ?title = PyHook_Tutorial http://pyhook.sourceforge.net/doc_1.5.0/ http://sourceforge.net/apps/mediawiki/pyhook/index.php ?title = Main_Page

解决方案

据我所知,目前还没有Python库,因此您将要调用本机API.好消息是PyObjC(最新OS发行版中内置的Python随附)通常使此操作变得容易.

有两个主要选项.为了使这两种方法都能正常工作,您的应用程序必须具有Cocoa/CoreFoundation运行循环(就像在Windows中一样,很多事情都要求您成为"Windows GUI可执行文件"而不是命令行可执行文件"),我赢了在这里不解释如何做. (如果您不知道如何,请找到一个很好的教程来用Python构建GUI应用程序,因为那是最简单的方法.)

简单的选项是Cocoa全局事件监视器API.但是,它有一些主要限制.您只会收到要发送到另一个应用程序的事件-这意味着媒体键,全局热键以及出于任何原因被忽略的键都不会显示.同样,您需要受信任的可访问性". (最简单的方法是要求用户在系统偏好设置"的通用访问"面板中全局将其打开.)

硬选项是Quartz事件点击API.它具有更大的灵活性,并且只需要完全适当的权限(取决于您使用的设置,可能包括对可访问性的信任和/或以root用户身份运行),并且功能强大得多,但是这需要花费很多时间开始工作还需要做更多的工作,如果您弄错了系统,则可能会弄糟您的系统(例如,通过吃掉所有击键和鼠标事件,使它们永远无法进入操作系统,并且只有通过电源按钮才能重新启动)./p>

有关所有相关功能的参考,请参见https://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html (用于Quartz事件).进行一些谷歌搜索应该在Objective C(对于NSEvent)或C(对于CGEventTap)中出现大量示例代码,但是在Python中却很少或没有,因此,我将展示一些小片段来说明如何移植样本到Python:

import Cocoa
def evthandler(event):
  pass # this is where you do stuff; see NSEvent documentation for event
observer = Cocoa.NSEvent.addGlobalMonitorForEventsMatchingMask_handler_(NSKeyDown, evthandler)
# when you're done
Cocoa.NSEvent.removeMonitor_(observer)

import Quartz
def evthandler(proxy, type, event, refcon):
    pass # Here's where you do your stuff; see CGEventTapCallback
    return event
source = Quartz.CGEventSourceCreate(Quartz.kCGEventSourceStateHIDSystemState)
tap = Quartz.CGEventTapCreate(Quartz.kCGSessionEventTap,
                              Quartz.kCGHeadInsertEventTap,
                              Quartz.kCGEventTapOptionListenOnly,
                              (Quartz.CGEventMaskBit(Quartz.kCGEventKeyDown) |
                               Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp)),
                              handler,
                              refcon)

Carbon事件(从InstallEventHandler开始)与Quartz事件大致处于同一级别.但是,Carbon已经过时了,最重要的是,很难从Python掌握,所以除非您有特定的理由要这么做,否则请不要这样做.

还有其他一些方法可以达到同一目的,例如,使用DYLD_INSERT_LIBRARIES或SIMBL将代码插入每个应用程序中-但是我想不出其他任何可以在纯Python中完成的事情.

I am actually working with pyHook, but I'd like to write my program for OS X too. If someone know such a module ... I've been looking on the internet for a while, but nothing really relevant.

-> The idea is to be able to record keystrokes outside the python app. My application is a community statistics builder, so it would be great to have statistics from OS X too.

Thanks in advance ;)

Edit: PyHook : Record keystrokes and other things outside the python app http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=PyHook_Tutorial http://pyhook.sourceforge.net/doc_1.5.0/ http://sourceforge.net/apps/mediawiki/pyhook/index.php?title=Main_Page

解决方案

As far as I know, there is no Python library for this, so you're going to be calling native APIs. The good news is that PyObjC (which comes with the built-in Python on recent OS releases) often makes that easy.

There are two major options. For either of these to work, your app has to have a Cocoa/CoreFoundation runloop (just as in Windows, a lot of things require you to be a "Windows GUI executable" rather than a "command line executable"), which I won't explain how to do here. (Find a good tutorial for building GUI apps in Python, if you don't know how, because that's the simplest way.)

The easy option is the Cocoa global event monitor API. However, it has some major limitations. You only get events that are going to another app--which means media keys, global hotkeys, and keys that are for whatever reason ignored will not show up. Also, you need to be "trusted for accessibility". (The simplest way to do that is to ask the user to turn it on globally, in the Universal Access panel of System Preferences.)

The hard option is the Quartz event tap API. It's a lot more flexible, and it only requires exactly the appropriate rights (which, depending on the settings you use, may include being trusted for accessibility and/or running as root), and it's a lot more powerful, but it takes a lot more work to get started, and it's possible to screw up your system if you get it wrong (e.g., by eating all keystrokes and mouse events so they never get to the OS and you can't reboot except with the power button).

For references on all of the relevant functions, see https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/nsevent_Class/Reference/Reference.html (for NSEvent) and https://developer.apple.com/library/mac/#documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html (for Quartz events). A bit of googling should turn up lots of sample code out there in Objective C (for NSEvent) or C (for CGEventTap), but little or nothing in Python, so I'll show some little fragments that illustrate how you'd port the samples to Python:

import Cocoa
def evthandler(event):
  pass # this is where you do stuff; see NSEvent documentation for event
observer = Cocoa.NSEvent.addGlobalMonitorForEventsMatchingMask_handler_(NSKeyDown, evthandler)
# when you're done
Cocoa.NSEvent.removeMonitor_(observer)

import Quartz
def evthandler(proxy, type, event, refcon):
    pass # Here's where you do your stuff; see CGEventTapCallback
    return event
source = Quartz.CGEventSourceCreate(Quartz.kCGEventSourceStateHIDSystemState)
tap = Quartz.CGEventTapCreate(Quartz.kCGSessionEventTap,
                              Quartz.kCGHeadInsertEventTap,
                              Quartz.kCGEventTapOptionListenOnly,
                              (Quartz.CGEventMaskBit(Quartz.kCGEventKeyDown) |
                               Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp)),
                              handler,
                              refcon)

Another option, at about the same level as Quartz events, is Carbon events (starting with InstallEventHandler). However, Carbon is obsolete, and on top of that, it's harder to get at from Python, so unless you have some specific reason to go this way, don't.

There are some other ways to get to the same point—e.g., use DYLD_INSERT_LIBRARIES or SIMBL to get some code inserted into each app—but I can't think of anything else that can be done in pure Python.

这篇关于类似于OS X上的pyHook的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆