使用Gtk和XLib的Python3中的全局热键 [英] Global hotkey in Python3 using Gtk and XLib

查看:308
本文介绍了使用Gtk和XLib的Python3中的全局热键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的X System应用程序保留在后台(并且在面板中作为指示符),并且无论用户处于活动状态如何,只要用户按下某个键,它都应该弹出. 类似于菜单应用.

My application for X System stays in background (and in panel as indicator) and should popup whenever user hits a key, no matter whatever be the active window. Similar to Menu app.

尝试了以下内容:

  1. 在Linux上的python中侦听全局键组合 但是找不到如何集成此Gtk主循环的方法.
  2. 使用Python gtk3在X上进行全局键绑定 这个问题的唯一答案是Python 2,它不起作用.
  1. Listening for global key-combinations in python on Linux But can't find how to integrate this Gtk main loop.
  2. Global keybinding on X using Python gtk3 The only answer for this question is Python 2 and doesn't work.

混合以上两个代码,我得到以下代码:

Mixing the above two, I got the following code:

from Xlib.display import Display
from Xlib import X, error
from Xlib.ext import record
from Xlib.protocol import rq
from gi.repository import Gtk, GObject, Gdk
import threading


class GlobalKeyBinding(GObject.GObject, threading.Thread):

    def __init__(self):

        GObject.GObject.__init__(self)
        threading.Thread.__init__(self)

        self.setDaemon(True)
        self.display = Display()

        self.Win = Gtk.Window()
        self.Win.add(Gtk.Label("Hello"))

        self.root = self.display.screen().root
        ctx = self.display.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,
            }])
        self.state = 0
        self.display.record_enable_context(ctx, self.handler)
        self.display.record_free_context(ctx)

    def handler(self, reply):
        data = reply.data
        wait_for_release = False
        while len(data):
            event, data = rq.EventField(None).parse_binary_value(
            data, self.display.display, None, None)
            # KEYCODE IS FOUND USERING event.detail
            print(event.detail)

            if event.type == X.KeyPress:
        # BUTTON PRESSED
                print("pressed")
                if not self.state:
                    self.Win.show_all()
                    self.state = 1
                else:
                    self.Win.hide()
                    self.state = 0
            elif event.type == X.KeyRelease:
        # BUTTON RELEASED
                print("released")

    def run(self):
        self.running = True
        while self.running:
            event = self.display.next_event () # registered keycode(or probably rather event) has been received.
            while Gtk.main_iteration():
                Gtk.main_iteration_do(True)


def main():
    print("starting...")
    Gdk.threads_init ()
    keybindings=GlobalKeyBinding()
    keybindings.start ()
    Gtk.main ()

main()

尽管这捕获了我的输入,但它从未显示该窗口. 请帮助:)

Though this catches my input, it never shows the window. Please help : )

推荐答案

因此不需要使用XLib.全局热键可以使用keybinder模块来实现. 示例:

So using XLib is not needed. Global Hotkey can be achieved using keybinder module. Example:

import gi
gi.require_versions({"Gtk": "3.0", "Gdk": "3.0", "Keybinder": "3.0"})
from gi.repository import Gtk, Keybinder


class A:
    def __init__(self):

        self.win = Gtk.Window()
        self.lab = Gtk.Label(label="Hello")

        self.win.add(self.lab)
        self.win.connect("destroy", Gtk.main_quit)
        self.win.show_all()
        # Basic setup of a window with a label

        self.count = 0

        key = Keybinder  # The module to bind keys
        key.bind("<control>m", self.say, "Hello")
        # key.bind(KEYCOMBINATION, FUNC, ARG)
        key.init()  # Call the mainloop something like Gtk.main()

    def say(self, key, msg):
        print(msg)
        self.lab.set_label(f"Pressed {key} {self.count} times")
        self.count += 1


A()  # Call the object
Gtk.main()  # Call the main loop

您可以在此处找到有关此模块的更多信息: https://github.com/engla/keybinder

You can find more about this module here : https://github.com/engla/keybinder

这篇关于使用Gtk和XLib的Python3中的全局热键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆