2012-06-12 34 views
4

我实际上使用pyHook,但我想写我的OS X程序。 如果有人知道这样一个模块......我一直在网上查找一段时间,但没有什么相关的。类似于OS X上的pyHook

- >这个想法是能够记录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

+0

pyHook是做什么的? –

+1

刚刚编辑了演示文稿。 pyHook让你记录python应用程序之外的击键(仅在Windows上),这通常用于例如键盘记录器。就我而言,我希望在OS之间建立统计数据,关于鼠标活动,击键和窗口(数量,时间等)。 pyHook是完美的在Windows上做这件事,所以我想弄清楚如何在OS X上做到这一点:) –

+0

在这里有几个有用的线程:但他们不讨论实际的库:http ://stackoverflow.com/questions/3258312/setwindowshookex-for-mac-os-x,http://stackoverflow.com/questions/4809251/keyboard-input-on-osx –

回答

9

据我所知,这里没有Python库,所以你会调用本地API。好消息是,PyObjC(在最新的操作系统发行版中附带了内置的Python)通常可以轻松实现。

有两个主要选项。对于其中的任何一种工作,你的应用必须有一个Cocoa/CoreFoundation runloop(就像在Windows中一样,许多事情要求你成为“Windows GUI可执行文件”而不是“命令行可执行文件”),我赢了不解释如何在这里做。 (如果你不知道怎么做,找一个用Python构建GUI应用程序的好教程,因为这是最简单的方法。)

简单的选项是Cocoa全局事件监视器API。但是,它有一些主要的限制。您只会收到其他应用的事件 - 这意味着媒体密钥,全局热键以及因任何原因被忽略的密钥都不会显示出来。此外,你需要被“信任可访问性”。 (最简单的方法是要求用户在系统偏好设置的通用访问面板中全局打开它。)

硬选项是Quartz事件点击API。它更加灵活,并且只需要恰当的权限(根据您使用的设置,可能包括受信任的可访问性和/或以root身份运行),并且它的功能更强大,但它需要很多更多的工作开始,如果你弄错了系统,可能会搞砸你的系统(例如,通过吃掉所有击键和鼠标事件,以便他们永远不会进入操作系统,除非使用电源按钮,否则无法重新启动)。

有关所有相关功能的参考,请参阅https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/nsevent_Class/Reference/Reference.html(适用于NSEvent)和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) 

另一种选择,在大约相同的水平石英的事件,是碳事件(开始用InstallEventHandler)。但是,Carbon已经过时了,除此之外,从Python中获取更困难,所以除非有特定的理由这样做,否则不要。

还有其他一些方法可以达到同样的目的 - 例如,使用DYLD_INSERT_LIBRARIES或SIMBL来获取插入到每个应用程序中的代码 - 但我无法想象在纯Python中可以完成的任何其他操作。

+0

非常感谢你长期和完整的答案!我会看看它,并保持联系;) –

相关问题