在Linux上的python中侦听全局键组合

在Linux上的python中侦听全局键组合

问题描述:

我刚刚编写了一个小程序,每隔几分钟就会从flickr下载一个新的墙纸.

I just wrote a little program which downloads a new wallpaper from flickr every few minutes.

现在,我想添加该功能以喜欢"壁纸,因此与不喜欢或不喜欢的壁纸相比,它的出现频率更高.

Now I want to add the capability to "like" a wallpaper, so it will occur more often than non-liked or disliked wallpapers.

我想为此功能分配一个全局键盘快捷键.

I'd like to assign a global keyboard-shortcut to this function.

例如:如果按ctrl + 7,它将在Python中执行某种赞"功能.

For example: If I press ctrl+7, it would execute some kind of "like" function in Python.

是否有任何库(例如,在JavaScript中,可以使用shortcut("ctrl-b", someFunction);定义快捷方式)

Are there any libraries for this (in JavaScript for example there's a library where I can define shortcuts with shortcut("ctrl-b", someFunction);)

否则,我将如何处理呢?我见过这个类似的问题,但它已经过时了.

Otherwise, how would I go round doing this? I've seen this similar SO question, but it's old.

我不知道有任何旨在扩展的库.但是,正如您的链接所述,pykeylogger的后端提供了如何执行此操作的示例,但是对于您而言,它似乎有些复杂.

I do not know of any libraries that are designed to be extended. However as your link stated the backend of pykeylogger gives an example of how to do it, but it does seem a little overcomplicated for you would need.

pykeylogger使用python-xlib模块捕获X显示屏上的按键.有人已经在 pastebin 上创建了一个更简单的示例.以下是按原样复制到此处的来源.

pykeylogger uses the python-xlib module to capture keypresses on the X display. Someone has already created a lighter example of how to go through this on pastebin. Below is the source from it copied here as-is.

from Xlib.display import Display
from Xlib import X
from Xlib.ext import record
from Xlib.protocol import rq

disp = None

def handler(reply):
    """ This function is called when a xlib event is fired """
    data = reply.data
    while len(data):
        event, data = rq.EventField(None).parse_binary_value(data, disp.display, None, None)

        # KEYCODE IS FOUND USERING event.detail
        print(event.detail)

        if event.type == X.KeyPress:
            # BUTTON PRESSED
            print("pressed")
        elif event.type == X.KeyRelease:
            # BUTTON RELEASED
            print("released")

# get current display
disp = Display()
root = disp.screen().root

# Monitor keypress and button press
ctx = disp.record_create_context(
            0,
            [record.AllClients],
            [{
                    'core_requests': (0, 0),
                    'core_replies': (0, 0),
                    'ext_requests': (0, 0, 0, 0),
                    'ext_replies': (0, 0, 0, 0),
                    'delivered_events': (0, 0),
                    'device_events': (X.KeyReleaseMask, X.ButtonReleaseMask),
                    'errors': (0, 0),
                    'client_started': False,
                    'client_died': False,
            }])
disp.record_enable_context(ctx, handler)
disp.record_free_context(ctx)

while 1:
    # Infinite wait, doesn't do anything as no events are grabbed
    event = root.display.next_event()

您将不得不扩展处理程序以适合您的需求,而不仅仅是将其打印到屏幕上,然后使其成为一个单独的线程.

You will have to extend the handler to fit your needs for instead of just printing to screen, and then make it into a separate thread.

(痛苦的)替代方法是直接聆听键盘,而无需依赖外部库或X会话.在Linux中,所有内容都是一个文件,您的键盘输入将位于/dev/input ,您可以在后台将其读取为文件,例如open('/dev/input/even2', 'rb').不建议这样做,因为它需要逐步升级的权限,找出哪个设备是键盘,然后创建自己的键盘映射.只是想让您知道必要的情况.

The (painful) alternative is to listen to the keyboard directly, without relying on external libraries or the X session. In linux everything is a file and your keyboard input will be in /dev/input that you could read as a file, for example open('/dev/input/even2', 'rb'), in the background. This is not suggested as it requires escalated permissions, figuring out which device is the keyboard, and then create your own keymapping. Just wanted to let you know what's possible if necessary.

也找到了使用Python gtk3在X上进行全局键绑定似乎有更多榜样的优点.

Also found Global keybinding on X using Python gtk3 which seems to have more example goodness.