3

そこで、いくつかの内部ヘルパーアプリケーションをMac OSX10.7に移植するように依頼されました。

プラットフォームに依存するコードはとにかく最小限であるため、すべてうまく機能しますが、1つのアプリケーションが機能するにはシステム全体のショートカット(つまり、 RegisterHotkey機能)が必要であり、Macでこれを行う方法に関するドキュメントが見つかりません。

プログラムはPython3.2でPyQtGUIを使用しています。Windowsに対応するコードは基本的に次のとおりです。

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

次に、ホットキーイベントを受信します。

def winEvent(self, msg):
    if msg.message == w32.WM_HOTKEY:
        self.handle_hotkey()
        return True, id(msg)
    return False, id(msg)

Pythonのバリアントは必要ないことに注意してください。簡単なc拡張機能を簡単に記述できます。したがって、C/objective-cソリューションも歓迎します。

4

3 に答える 3

9

私は最近、マルチメディアキーをキャプチャするquodlibetの拡張機能をコーディングしました(quodlibet自体に吸収されたため)。セットアップにも同じプロセスが適用されます。

これを実現するために、QuartzCGEventTapCreateフックとイベントループ、およびCocoaAppKitフレームワークを使用してキーコードを解読しました。

次のコードは、グローバルキーの押下が渡される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()

システム定義のキー(メディアキー)のみのタップを定義しました。別のイベントマスクを指定する必要があります(CGEventMaskBit1つ以上のイベントタイプを使用)。たとえばQuartz.CGEventMaskBit(Quartz.kCGEventKeyUp)、キーアップイベントの場合。

コールバックには次の署名が必要です(CGEventTapCallBackQuartz APIのメソッドを実装します:

def keyboardTapCallback(proxy, type_, event, refcon):
    # Convert the Quartz CGEvent into something more useful
    keyEvent = NSEvent.eventWithCGEvent_(event)

NSEventMacマルチメディアキーで見つけたすべての情報がそのクラスを参照していたため、Quartzイベントをに変換しました。

原則として、AppKit APIでも同じことを実現できますが、PythonアプリケーションはMacアプリケーション(Dockにアイコンなどで表示されます)として扱われますが、これは完全にバックグラウンドで保持する必要があります。

于 2012-07-05T16:55:49.167 に答える
2

グーグルの力を使って、私はこのコードスニペットを見つけました。これはMacOSXのグローバルホットキーの登録を可能にします

フレームワークを追加する必要があります。Objective-CセルフポインターをC関数に渡す場合Carbonは、おそらくブリッジキャストを追加する必要があります。ARC

少なくとも、次のことも行う必要があります。

#import <Carbon/Carbon.h>

キーコードは、仮想キーコードを説明するこのページで見ることができます。

于 2012-07-05T15:56:17.283 に答える
0

シェルコマンドを呼び出したり、SafariやPHOTOSHOPなどのUIアプリケーションを起動したりできるカスタムグローバルシステムショートカットをサポートするhammerspoonについて誰も言及していないのはなぜですか。

以下は、グローバルホットキーを使用してシェル関数を呼び出す方法を示す私が書いた例です。 https://gist.github.com/BigSully/0e59ab97f148bc167ea19dbd42ebef4b

hs.executeを使用して、非対話型または対話型のシェルコマンドを実行します。

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "P", function()
  local output = hs.execute("toggleProxy", true)
  hs.alert.show(output)
end)

またはhs.application.launchOrFocusを使用してアプリケーションhs.application.launchOrFocus( "Safari")を起動します

于 2020-01-17T15:41:50.243 に答える