python3 全局热键,使用Gtk和XLib的Python3中的全局热键

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.

Tried the following:

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 : )

解决方案

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("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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值