2010-02-25 14 views
9

Mac'imde Python'da yazılmış bir uygulamada global fare olaylarını (bir uygulamaya bağlı değil) dinlemem gerekiyor.Mac üzerinde Python'da bir fare olayı nasıl dinleyebilirim?

Ben PyObjC kullanıyorum, ama bunu anlamaya olamaz. Düz ObjC örnekleri veya diğer Python teknikleri de takdir edildi. Bugüne kadar

Kodum:

from Quartz import * 
def MyFunction(proxy, type, event): 
    print event 

CGEventTapCreate(kCGHIDEventTap, kCGTailAppendEventTap, kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction) 

== Segmentasyon hatası

ben sonradan bir olay kaynağına eklemeniz gerekir biliyorum ama bu ilk çalışma almak gerekir.

[güncelleme]

PyObjC formu MacPorts segfault çözüldü kullanarak, peki şimdi bu yazdım:

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(); 

Ama bu sadece sonsuza çalışır ve yanlış nedir fare olaylara yanıt vermiyor? onlar çağrıldığında

cevap

2

CGEventTapCreate öğesinin dördüncü parametresi CGEventMask eventsOfInterest olup,türünde bir numara olan kCGEventLeftMouseDown verdiniz. Tamsayı sabiti yerine, bit maskesi içerisindeki uygun biti çevirmeniz gerekir. Bundan Bunun yerine CGEventMaskBit

kullanarak bunu yapabilirsiniz:

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 
    kCGEventTapOptionListenOnly, kCGEventLeftMouseDown, MyFunction, None) 

Bunu yapabiliriz: eşdeğer

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 
    kCGEventTapOptionListenOnly, CGEventMaskBit(kCGEventLeftMouseDown), 
    MyFunction, None) 

ya:

tap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 
    kCGEventTapOptionListenOnly, (1 << kCGEventLeftMouseDown), 
    MyFunction, None) 
+0

bu doğru cevap olmalı –

-1

Birincisi,CGEventTapCreate ve CGEventTapCreateForPSN bazı bellek sızıntısı. Bellek yönetimi sorunlarından kaçınmak için bu gereklidir. Bu nedenle, bu işlevleri çağırmamak için tavsiye edilen , en azından bir kere kez arayın.

Şimdi, fare olayı şöyle çalışır:

evt = CGEventCreateMouseEvent(None, kCGEventLeftMouseDown, (80, 90), kCGMouseButtonLeft) 
self.failUnlessIsInstance(evt, CGEventRef) 
+1

ben göndermek istemiyorum olaylar, onları dinlemek istiyorum. CGEventCreateMouseEvent olay oluşturmaya değil etkinlik oluşturmak içindir. – Pepijn

+0

Üzgünüm. Yanlış kod örneğini vermekle uğraştım. –

+1

Size verdiğimi düşündüğüm Tap Event için başka bir yöntem var. –

1

CGEventTapCreate (http://developer.apple.com/mac/library/documentation/Carbon/Reference/QuartzEventServicesRef/Reference/reference.html#//apple_ref/c/func/CGEventTapCreate) için dokümantasyon kCGHIDEventTap kullanmak kök olması gerektiğini söylüyor. Komut dosyanızı root olarak mı çalıştırıyorsunuz? Eğer varsa, ayrıca musluk Yok olup olmadığını kontrol etmelidir

(sudo, bunu yapmanın bir yolu); Bu problemi daraltmaya yardımcı olacak. Belgedeki CGEventTapCreate'un NULL döndürmesine neden olabilecek çeşitli hata koşulları vardır, bu Python'da Yok olarak yansıtılmalıdır.

+0

Sudo veya farketmez, hem dokunun hem de runLoopSource bir şey içeriyor. KCGHIDEventTap için bir alternatif var mı? CFRunLoopRunInMode (kCFRunLoopDefaultMode, 20, False) 'nın 20 saniye boyunca çalıştığını, ancak True bipleri hemen sağladığını, ancak yine de MyFunction'dan çıkmadığını fark ettim. – Pepijn

+0

Yazdırmaya çalıştığınız CGEventRef dizgisi ile ilgili bir şey olabilir mi? Belki de emin olmak için MyFunction'da sabit bir dizgi basmayı deneyebilirsiniz. Bunun dışında, gerçekten bilmiyorum. –

+0

Sadece 'hi' yazdırmaya çalıştım, ama bu da işe yaramadı. Stdout'un farklı şekilde ayarlandığı bir işlev çağrılabilir mi? – Pepijn