倾听键盘事件而不捕获它们?

我正在编写一个命令行应用程序,它在X Windows中监听Control键释放事件,并在检测到它时警告另一个进程。

作为GNU / Linux的新手,我宁愿避免使用GCC,因此我正在寻找一种基于脚本的解决方案。 因为我知道一些Python,所以选择一个基于Python的解决方案似乎很自然,并且在清除Internet上的示例并阅读Python Xlib文档后,我将这些程序合并在一起,但有一点需要注意:它会陷入陷阱事件而不是仅仅听他们(我的意思是这些事件不再通过它们被引导到的应用程序)。

我通过运行“xev”来跟踪控制键代码。 由于我重新映射了我的修改键,在您的系统上它们可能会有所不同。

为了简单起见,我忽略了处理外部过程的代码。

感谢您的帮助。

软件:

  • Python 2.7.2

  • Python Xlib 0.15 RC1

  • Perl v5.10.1

  • Debian GNU / Linux版本:6.0.3

  • 内核版本:Linux debian 2.6.32-5-686

  • 编辑:我无法弄清楚的是,键盘事件不会被困住,除非他们被处理(在我的程序中,这意味着'print'KeyRelease''行被执行)。 因为在我的代码中,我不会在Xlib或事件对象上调用任何方法,但我不明白处理中的差异在哪里。

    编辑2:除了使用Xlib之外,还有其他解决方案的建议。

    编辑3:我也了解Perl,并且可以提供帮助的Perl库的建议也是受欢迎的,只要它们不需要最新版本的系统库,因为Debian在其存储库中可用的软件包时出现臭名昭着的问题,并且编译并且安装最后版本的库可能会很困难,如果它们有很多依赖关系的话(我尝试安装PyGTK,但是在未能引用我安装的最新GLib之后放弃了)。

        #!/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)
    

    感谢Croad Langshan提到的pykeylogger库,以及这个库的作者Tim Alexander提供的有用示例代码,我已经能够将我的程序更改为:

        #!/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()
    

    这个程序完成我的目标没有任何问题。 您可以阅读“事件”对象的字段以获取有关该事件的更多信息(请参阅“pyxhook.py”的源代码)。


    您需要使用XRecord扩展名。 它可以与pyxlib(在其他答案中提到的pykeylogger使用这个)一起使用,或者通过ctypes包装libX11和libXtst(就像我在synaptiks中那样)。

    但是请注意,使用xrecord进行编程(以及一般情况下也适用于XLib)是很难的,因为API记录很糟糕,而且非常的巴洛克式和反直觉。


    推测这个项目必须有解决这个问题的代码:

    http://sourceforge.net/apps/mediawiki/pykeylogger/index.php?title=Main_Page

    链接地址: http://www.djcxy.com/p/18429.html

    上一篇: Listening to keyboard events without trapping them?

    下一篇: Receive keyboard events for any language in Android