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

2024-10-01 11:22:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个命令行应用程序,它监听X窗口中的控制键释放事件,并在检测到这些事件时向另一个进程发出警报。

作为GNU/Linux的新手,我更希望避免与GCC打交道,因此我正在寻找一个基于脚本的解决方案。因为我懂一点Python,所以很自然地选择了基于Python的解决方案,在浏览了Internet上的示例和Python Xlib文档之后,我将这些程序组合在一起,这些程序可以工作,但有一点需要注意:它会捕获事件,而不是仅仅监听它们(我的意思是这样的事件不再传递给它们最初被指向的应用程序)。

我通过运行“xev”来追踪控制键代码。因为我重新映射了修改键,所以在你的系统上它们可能不同。

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

谢谢你的帮助。

软件:

  • Python 2.7.2

  • Python Xlib 0.15 RC1

  • Perl 5.10.1版

  • Debian GNU/Linux版本:6.0.3

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

编辑:我不明白的是,键盘事件不会被捕获,除非它们被处理(在我的程序中,这意味着“print”keyrease“行被执行)。因为在我的代码中,我既不调用Xlib上的任何方法,也不调用事件对象上的任何方法,所以我不知道处理过程中的区别在哪里。

EDIT2:除了使用Xlib之外,还欢迎对其他解决方案的建议。

EDIT3:我也了解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)

Tags: 代码程序版本eventforlinuxdisplay事件
3条回答

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

但是,请注意,使用xrecord(在某种程度上也使用XLib)编程有点困难,因为API文档记录得很糟糕,而且相当巴洛克和反直觉。

感谢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()

这个程序毫无问题地实现了我的目标。您可以读取“event”对象的字段以获取有关该事件的更多信息(请参见“pyxhook.py”的源代码)。

大概这个项目必须有解决这个问题的代码:

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

相关问题 更多 >