J'ai récemment codé un extension à quodlibet capturant des clés multimédia (depuis absorbé dans quodlibet lui-même); pour votre configuration, le même processus s'applique.
J'ai utilisé la boucle CGEventTapCreate
hook de Quartz et la structure Cocoa AppKit pour déchiffrer les codes clés pour y parvenir.
Le code suivant enregistre un rappel de python qui est passé touches globales, et lance la boucle d'événement:
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()
je définissais un robinet pour les clés définis par le système uniquement (touches multimédias); vous devrez spécifier un masque d'événement différent (CGEventMaskBit
avec un ou plusieurs Event Types); par exemple. Quartz.CGEventMaskBit(Quartz.kCGEventKeyUp)
pour les événements key up.
Le rappel doit avoir la signature suivante (il implémente le CGEventTapCallBack
method from the Quartz API:
def keyboardTapCallback(proxy, type_, event, refcon):
# Convert the Quartz CGEvent into something more useful
keyEvent = NSEvent.eventWithCGEvent_(event)
I converti l'événement à quartz dans un NSEvent
, parce que toutes les informations que je pouvais trouver sur les touches multimédias Mac faisait référence à cette classe. En principe, vous pouvez obtenir la même chose avec les API AppKit, mais votre application Python est traitée comme une application Mac (visible dans le Dock avec une icône et tout), alors que je voulais que cela reste dans le fond complètement
Merci, ressemble exactement à ce dont j'ai besoin. J'ai compilé pyobjc pour Python3 (légèrement plus encombrant que prévu), mais lors de l'exécution du code, il m'indique que l'attribut 'AttributeError:' module 'n'a pas d'attribut' CGEventTapCreate''. pyobjc devrait fonctionner avec python3, alors je manque quelque chose ou l'API n'est-elle pas complètement portée? – Voo
@Voo: Désolé, aucune idée; J'ai seulement travaillé avec python 2.7 et pyobjc. –
Débogué le problème un peu le matin et l'a réparé. Le plat à emporter est: python3 et pyobjc n'est vraiment pas recommandé, mais on peut le faire fonctionner. Et c'était certainement moins de travail que d'apprendre le framework cacao ou de rétroporter l'application sur python2. Merci encore pour l'aide. – Voo