J'ai besoin d'écouter les événements mondiaux de la souris (non liés à une application) sur mon Mac dans une application écrite dans Python.
J'utilise Pyobjc, mais je ne peux pas comprendre comment le faire. Les exemples unis objc ou d'autres techniques de python ont également apprécié. P>
Mon code jusqu'à présent: p>
from Quartz import * def MyFunction(p, t, e, c): print e tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction, None) runLoopSource = CFMachPortCreateRunLoopSource(None, tap, 0); CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode); CGEventTapEnable(tap, True); CFRunLoopRun();
3 Réponses :
Premier, cgeventtapcreate strong> et cgeventtapcreateforpsn strong> fuite de la mémoire quand ils
sont appelés. Ceci est nécessaire pour éviter les problèmes de gestion de la mémoire. Il est donc
conseillé de ne pas appeler ces fonctions, les appelent au moins un petit nombre
de fois. Maintenant, un événement de souris fonctionne comme ceci: P> evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft)
self.failUnlessIsInstance(evt, CGEventRef)
Je ne veux pas envoyer d'événements, je veux écouter pour eux. CGEventCreatemouseevent est destiné à créer des événements, pas de robinets d'événement.
Il existe une autre méthode pour l'événement TAP que je pensais que je vous donnais.
La documentation pour cgeventtapcreate strong> ( http://developer.apple.com/mac/library/documentation/carbon/reference/quartzeventservicesref/reference/reference.html#//apple_ref/c/func / Cgeventtaprcreate ) dit que vous devez être root à utiliser kcghideventTap. Exécutez votre script en tant que root? (sudo est une façon de le faire) p>
Si vous êtes, vous devez également vérifier si le robinet n'est pas; cela aidera à réduire le problème. Il existe plusieurs conditions d'erreur énumérées dans la documentation pouvant causer
Sudo ou non ne fait pas une différence, le robinet et le runloopsource contiennent quelque chose. Y a-t-il une alternative à KCGHIdeventTap? J'ai remarqué que cfrunloopruninmode (kcfrunloopdefauldmode, 20, false) fonctionne pendant 20 secondes, mais la fourniture de véritables extrémités immédiatement, mais elle n'est toujours pas sortie de la mycée.
Pourrait-il être quelque chose à voir avec le stringifiant le cgeventtref que vous essayez d'imprimer? Peut-être que vous pourriez essayer d'imprimer une chaîne constante dans la mycée juste pour vous assurer. Autre que cela, je ne sais pas vraiment.
J'ai essayé de simplement imprimer 'salut', mais cela n'a pas aidé non plus. Pourrait-il être que la fonction est appelée quelque part où stdout est défini différemment?
Le quatrième paramètre de CGENTTTAPCreate est donc au lieu de cela: p> Nous pouvons faire ceci: p> CGENTMASK EFRESOFIEREST CODE>, et vous l'avez donné
KCGENventLeftMouseDown code> qui est un énorme de type
_cgeventtype code>. Au lieu de la constante entière, vous devez retourner le bit approprié dans le masque de bit. Vous pouvez le faire en utilisant
cgeventmaskbit code>
tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap,
kCGEventTapOptionListenOnly, (1 << kCGEventLeftMouseDown),
MyFunction, None)