Mac OS X的系统范围快捷方式

2024-05-23 22:54:00 发布

您现在位置:Python中文网/ 问答频道 /正文

所以我被要求将一些内部助手应用程序移植到macosx10.7上。在

这一切都很好,因为依赖于平台的代码无论如何都是最少的,但是一个应用程序需要一个系统范围内的快捷方式来运行(即RegisterHotkey功能),我找不到任何关于如何在Mac上实现这一点的文档。在

该程序使用PyqtGUI和Python3.2。windows对应的代码基本上是:

def register_hotkey(self):
    hwnd = int(self.winId())
    modifiers, key = self._get_hotkey()
    user32.RegisterHotKey(hwnd, self._MESSAGE_ID, modifiers, key)

然后接收热键事件:

^{pr2}$

请注意,我不需要python变体,我可以很容易地编写一个简单的c扩展—所以c/objective-c解决方案也很受欢迎。在


Tags: key代码文档self功能应用程序mac系统
2条回答

我最近编写了一个extensionquodlibet捕获多媒体密钥的代码(因为它被吸收到了qodlibet中);对于您的设置,同样的过程也适用。在

我使用Quartz^{} hook和事件循环,以及Cocoa AppKit框架来破译密钥代码来实现这一点。在

以下代码注册一个python回调,该回调被传递给全局键按下,并启动事件循环:

import Quartz
from AppKit import NSKeyUp, NSSystemDefined, NSEvent

# Set up a tap, with type of tap, location, options and event mask
tap = Quartz.CGEventTapCreate(
    Quartz.kCGSessionEventTap, # Session level is enough for our needs
    Quartz.kCGHeadInsertEventTap, # Insert wherever, we do not filter
    Quartz.kCGEventTapOptionListenOnly, # Listening is enough
    Quartz.CGEventMaskBit(NSSystemDefined), # NSSystemDefined for media keys
    keyboardTapCallback,
    None
)

runLoopSource = Quartz.CFMachPortCreateRunLoopSource(None, tap, 0)
Quartz.CFRunLoopAddSource(
    Quartz.CFRunLoopGetCurrent(),
    runLoopSource,
    Quartz.kCFRunLoopDefaultMode
)
# Enable the tap
Quartz.CGEventTapEnable(tap, True)
# and run! This won't return until we exit or are terminated.
Quartz.CFRunLoopRun()

我只为系统定义的键(媒体键)定义了一个tap;您必须指定一个不同的事件掩码(CGEventMaskBit和一个或多个Event Types);例如,Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp)用于键启动事件。在

回调应该有以下签名(它实现了^{} method from the Quartz API

^{pr2}$

我将Quartz事件转换为^{},因为我在Mac多媒体密钥上能找到的所有信息都与该类有关。在

原则上,你也可以用appkitapi实现同样的功能,但是你的Python应用程序被视为一个Mac应用程序(在Dock中可以看到一个图标和所有东西),而我希望它完全保持在后台。在

利用google的强大功能,我找到了this snippet of code,它允许注册macosx的全局热键

当将Objective-C self指针传递给C函数时,您需要添加Carbon框架,以及{}的桥接转换。在

至少,您还需要:

#import <Carbon/Carbon.h>

密钥码可以看到on this page explaining the virtual key codes。在

相关问题 更多 >