Xiaoe Keyboard 🎹
一个轻量、精准的 Python 全局热键管理器。基于 pynput 封装,专为需要处理复杂组合键和 UI 线程安全的桌面应用设计。
✨ 为什么选择它?
- 🧠 智能组合键匹配:底层使用
set子集算法匹配按键,完全无视用户按下组合键的先后顺序。 - 🎯 贪心精准触发:同时注册
Ctrl+D和Ctrl+Shift+D时,只会精准触发匹配度最高的那个,不会发生冲突。 - 🎛️ 完美的“预览-保存”交互:支持
validate_keys_fun拦截机制。用户按下快捷键后,可以先在 UI 上预览(如:"你即将设置为 Ctrl+C"),用户点“确认”后再真正应用保存,体验极其优雅。也可以不设置validate_keys_fun,用户松手后立刻触发保存。传入你的保存方法save_fun,比如说将按键存储在配置文件中,它将在触发保存后调用。
📦 安装
pip install xiaoe-keyboard
🚀 快速上手
只需三步,即可监听全局快捷键:
from xiaoe_keyboard import Keyboard
def my_action():
print("你按下了 Ctrl + D!")
# value 必须是 set 类型
hotkey_list = [
{'name': '我的热键', 'value': {'ctrl_l', 'd'}, 'down_fun': my_action}
]
# 启动监听
kb = Keyboard(hotkey_list)
input("按回车键退出程序...\n")
📖 进阶用法:动态设置热键(配合 Tkinter)
在实际桌面开发中,我们经常需要让用户“自定义快捷键”。以下演示了如何配合 Tkinter 实现完美的交互流程:
import tkinter as tk
from typing import List
from xiaoe_keyboard import Keyboard, HotkeyType
config = {
'操作a': ['ctrl_l', 'D']
}
win = tk.Tk()
win.geometry("300x200")
# 1. 定义初始热键
hotkey_list: List[HotkeyType] = [
{'name': '测试热键', 'value': set(config['操作a']), 'down_fun': lambda: print("执行了操作a!"), 'up_fun': lambda: print("松开了操作a!")}
]
def flash_get_now_key_label():
"""用于更新标签按键值"""
label.config(text = f"当前热键: 【{'】+【'.join(config['操作a'])}】")
def update_btn_status(is_change):
"""用于更新按钮文字"""
if is_change:
text = "修改热键"
else:
text = "取消设置"
btn.config(text=text)
# 2. 定义保存和预处理函数
def save_fun(name, value):
"""保存按键时的操作"""
value = list(value)
print(f"[已保存] {name} -> {value}")
config['操作a'] = value.copy()
flash_get_now_key_label()
update_btn_status(True)
will_save_hotkey = {}
def validate_keys_fun(name, value):
"""用户松手后,先触发这里,用于在界面上展示预览"""
will_save_hotkey[name] = value
label.config(text=f"即将设置为: {value} (请点保存)")
# 3. 实例化 Keyboard,传入调用回调的函数 run_fun_callback 保证线程安全
kb = Keyboard(
hotkey_list,
run_fun_callback=lambda func: win.after(0, func),
save_fun=save_fun,
validate_keys_fun=validate_keys_fun
)
# 4. UI 交互逻辑
label = tk.Label(win)
flash_get_now_key_label()
label.pack(pady=10)
def start_setting():
if kb.get_hotkey_setting() is None and not will_save_hotkey:
update_btn_status(False)
label.config(text="请按下你要设置的组合键...")
kb.set_hotkey_setting('测试热键') # 开启读取模式
else:
update_btn_status(True)
kb.set_hotkey_setting(None) # 关闭读取模式
flash_get_now_key_label()
will_save_hotkey.clear()
btn = tk.Button(win, command=start_setting)
update_btn_status(True)
btn.pack(pady=5)
def do_save():
if will_save_hotkey:
for name, value in will_save_hotkey.items():
kb.set_one_hotkey_dict(name, value) # 确认应用并触发 save_fun
will_save_hotkey.clear()
save_btn = tk.Button(win, text="保存设置", command=do_save)
save_btn.pack(pady=5)
win.mainloop()
📝 核心参数说明
hotkey_list: 热键配置列表,字典格式。value必须是set。如果需要解绑按键,设置{None}即可忽略该按键。run_fun_callback: 传入能在UI线程调用回调函数的函数。
# tkinter:
run_fun_callback=lambda func: win.after(0, func)
# qt(这里使用传递字典信号的方式):
class App(QWidget):
run_signal = QtCore.pyqtSignal(dict)
def __init__(self):
self.run_signal.connect(
lambda func_dict: func_dict['func']()
)
def run_func(self, func):
run_signal.emit({'func': func})
app = App()
run_fun_callback=app.run_func # 传入xiaoe_keyboard的参数
save_fun: 当热键被成功应用/保存时触动的回调。validate_keys_fun: 如果提供此项,用户松开按键时不会立刻保存,而是触发此函数。你需要自行在 UI 上暂存数据,并在用户点击“确认”后手动调用set_one_hotkey_dict()。如果你不提供该参数,当用户松开第一个按键后会立刻触发保存。
📄 开源协议
基于 MIT License 开源,自由使用,保留署名即可。
Author: 一只黄小娥
Url: [https://www.yzhxe.cn/]
Metadata
Release files for xiaoe-keyboard 6.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| xiaoe_keyboard-6.1.0.tar.gz | 11.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| xiaoe_keyboard-6.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.6 kB
Release files / xiaoe_keyboard-6.1.0.tar.gz
| Download URL | xiaoe_keyboard-6.1.0.tar.gz |
|---|---|
| Size | 11.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
908957de51184c18a4d1bc3fcdeb52820b8ad3fda65cafb7da365a7169819da5
|
|
BLAKE2b-256 checksum How to use checksums |
fee7ad54e2830348810c22f674d404414e891e3c4e0650babcbc681a2669b086
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Release files / xiaoe_keyboard-6.1.0-py3-none-any.whl
| Download URL | xiaoe_keyboard-6.1.0-py3-none-any.whl |
|---|---|
| Size | 9.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
17a8fe2332374d94d51f3bdb3aebb1f56d18aef317067158580f03b7aadefa0b
|
|
BLAKE2b-256 checksum How to use checksums |
9765e6d511b7c9f32d5677d2ce7aeae5c2b01883922b53ccfdc6b696ed60b054
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.13
|
Security for xiaoe-keyboard 6.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.