2012-02-08 18 views
14

Tôi đang viết một ứng dụng dòng lệnh để nghe các sự kiện phát hành phím Control trong X Windows và cảnh báo một quá trình khác khi phát hiện chúng.Lắng nghe các sự kiện bàn phím mà không phải bẫy chúng?

Làm quen với GNU/Linux, tôi muốn tránh xáo trộn với GCC và do đó tôi đang tìm giải pháp dựa trên tập lệnh. Vì tôi biết một chút về Python, có vẻ như tự nhiên để tìm giải pháp dựa trên Python, và sau khi quét Internet để xem các ví dụ và đọc tài liệu Python Xlib, tôi đã đặt các chương trình này hoạt động, nhưng với một cảnh báo: nó bẫy sự kiện thay vì chỉ lắng nghe họ (tôi có nghĩa là các sự kiện như vậy không được thông qua nữa cho ứng dụng mà họ đã được hướng dẫn ở nơi đầu tiên).

Tôi đã theo dõi xuống Mã khóa kiểm soát bằng cách chạy "xev". Kể từ khi tôi đã remapped phím bổ trợ của tôi, trên hệ thống của bạn họ có thể khác nhau.

Để giữ mọi thứ đơn giản, tôi đã bỏ qua mã liên quan đến quy trình bên ngoài.

Cảm ơn sự giúp đỡ của bạn.

phần mềm:

  • Python 2.7.2

  • Python Xlib 0,15 RC1

  • Perl v5.10.1

  • Debian GNU/Linux phiên bản: 6.0.3

  • Kernel v ersion: Linux debian 2.6.32-5-686

EDIT: Những gì tôi không thể bị mắc kẹt trừ khi chúng được xử lý (trong chương trình của tôi, điều này có nghĩa là dòng 'in "KeyRelease" 'được thực hiện). Kể từ trong mã của tôi, tôi không gọi bất kỳ phương pháp hoặc trên Xlib hoặc trên đối tượng sự kiện, tôi không hiểu nơi khác biệt trong chế biến nằm.

EDIT2: Đề xuất về các giải pháp thay thế ngoài việc sử dụng Xlib cũng được hoan nghênh.

EDIT3: Tôi cũng biết Perl và các đề xuất về thư viện Perl cũng có thể được hoan nghênh miễn là chúng không yêu cầu các phiên bản thư viện hệ thống gần đây, vì Debian nổi tiếng bị chậm lại khi nói đến các gói sẵn có kho, biên dịch và cài đặt các phiên bản mới nhất của thư viện có thể khó khăn nếu chúng có nhiều phụ thuộc (tôi đã thử cài đặt PyGTK, nhưng đã bỏ sau khi không tham khảo GLib cập nhật mà tôi đã cài đặt).

#!/usr/bin/env python 

    from Xlib.display import Display 
    from Xlib import X 

    Control_R = 64 # Keycode for right Control. 
    Control_L = 108 # Keycode for left Control. 
    keycodes = [Control_R, Control_L] # Keycodes we are listening for. 

    # Handle X events. 
    def handle_event(event): 
     # Let us know whether this event is about a Key Release of 
     # one of the key we are interest in. 
     if event.type == X.KeyRelease: 
      keycode = event.detail 
      if keycode in keycodes: 
       print "KeyRelease" 

    # Objects needed to call Xlib. 
    display = Display() 
    root = display.screen().root 

    # Tell the X server we want to catch KeyRelease events. 
    root.change_attributes(event_mask = X.KeyReleaseMask) 

    # Grab those keys. 
    for keycode in keycodes: 
     root.grab_key(keycode, X.AnyModifier, 1, X.GrabModeAsync, X.GrabModeAsync) 

    # Event loop. 
    while 1: 
     event = root.display.next_event() 
     handle_event(event) 

Trả lời

2

Bạn cần phải sử dụng phần mở rộng XRecord. Nó có thể được sử dụng với pyxlib (pykeylogger được đề cập trong câu trả lời khác sử dụng điều này), hoặc bằng cách gói libX11 và libXtst qua ctypes (như tôi đã làm trong synaptiks). Tuy nhiên, lưu ý rằng, lập trình với xrecord (và ở một mức độ nào đó với XLib nói chung) là một số khó khăn, bởi vì API bị ghi lại một cách tồi tệ, và khá baroque và phản trực giác.

+0

Cảm ơn. Tôi sẽ xem xét XRecord. Tuy nhiên, tôi đã thêm một vài ghi chú cho câu hỏi của tôi bởi vì có vẻ như với tôi rằng một giải pháp ở gần góc, vì mã của tôi không bẫy tất cả các sự kiện. –

11

Nhờ thư viện pykeylogger đề cập bởi Croad Langshan, và mã ví dụ hữu ích được cung cấp bởi Tim Alexander, tác giả của thư viện như vậy, tôi đã có thể thay đổi chương trình của tôi để:

#!/usr/bin/env python 

    from pyxhook import HookManager 

    watched_keys = ["Control_R", "Control_L"] 

    def handle_event (event): 
     if event.Key in watched_keys: 
      print "KeyRelease" 


    hm = HookManager() 
    hm.HookKeyboard() 
    hm.KeyUp = handle_event 
    hm.start() 

này chương trình hoàn thành mục tiêu của tôi mà không có bất kỳ vấn đề nào. Bạn có thể đọc các trường của đối tượng "sự kiện" để biết thêm thông tin về sự kiện (xem mã nguồn của "pyxhook.py").

1

Lưu ý rằng phần mở rộng XRecord tiếp tục bị hỏng trong một vài bản phân phối. Lý do tôi đã không quay trở lại và cập nhật thư viện đó một thời gian là vì nó đã bị hỏng trong Ubuntu cho nhiều bản phát hành. Có một cách để làm điều đó là tốt với một lớp phủ XInput, (tôi nói) nhưng tôi không bao giờ theo đuổi điều đó bởi vì tôi không muốn đối phó với một lớp phủ hơn là hooking các sự kiện X trực tiếp.

Nhận xét lại nếu có bất kỳ vấn đề nào với việc sử dụng mã trong lib pyxhook, tôi đã cố gắng làm cho nó đơn giản/mạnh mẽ nhất có thể, nhưng tôi có thể đã bỏ lỡ nội dung khi đặt nó lại với nhau. Nó đã được một thời gian trước đây.