为什么要开发这个插件
我有一个没有状态指示灯的键盘,
我需要保证它占用系统资源足够少,并且代码不能过于复杂
明确插件目标
- 实时监听 NumLock 键状态变更
- 在屏幕右下角弹出状态提示框(ON / OFF)
- 提示窗在 1.5 秒后自动隐藏
- 支持按
-键退出程序,并显示“退出”提示
选择开发语言与技术栈
选型理由:
- 使用
Python是为了开发效率高,语法简洁 - 使用
tkinter快速构建轻量 GUI,无需额外依赖 - 使用
keyboard实现全局键盘监听 - 使用
ctypes获取 NumLock 状态(调用的 Windows API节约系统资源)
具体实现
NumLock状态检测
def get_numlock_state(self):
return bool(ctypes.WinDLL("User32.dll").GetKeyState(0x90) & 1)
0x90是 NumLock 的虚拟键码调用
GetKeyState获取当前开关状态(ON 为 1)
主界面浮窗
使用 tkinter.Tk() 创建无边框窗口:
self.root.overrideredirect(True) # 去除边框
self.root.attributes('-topmost', True) # 保持置顶
self.root.attributes('-alpha', 0.8) # 设置为 80% 透明
窗口大小:
130x45位置:屏幕右下角偏移一点(避免压到任务栏)
显示状态文字
self.label = tk.Label(
self.root,
fg="lime",
bg="black",
font=("Consolas", 16, "bold") # 加粗字体
)
状态变为 ON 时显示绿色文字
状态变为 OFF 时显示红色文字
加粗字体突出提示效果
监听 NumLock 键变化
def keyboard_listener(self):
def on_press(event):
if event.name == "num lock":
self.queue.put("update")
keyboard.on_press(on_press)
- 通过
keyboard.on_press捕捉按键 - 使用
Queue将事件传递给主线程刷新界面(避免跨线程修改 UI)
弹窗提示并自动隐藏
self.root.deiconify()
self.fade_timer = threading.Timer(1.5, self.safe_withdraw)
self.fade_timer.start()
- 每次状态变化时显示窗口
- 启动定时器,在 1.5 秒后自动调用
withdraw()隐藏窗口
退出功能
keyboard.wait("-")
self.label.config(text="退出", fg="yellow")
self.root.deiconify()
time.sleep(1)
self.root.quit()
- 监听
-键作为退出信号 - 显示“退出”提示
- 延迟 1 秒关闭主窗口
结构梳理
| 线程名称 | 功能说明 |
|---|---|
| 主线程 | 显示 UI,处理事件队列 |
keyboard_listener |
实时监听 NumLock 键 |
exit_listener |
监听退出按键并触发退出流程 |
成品效果
//TODO 扩展
本插件实现了对键盘 NumLock 状态的轻量提示功能,界面简洁、资源占用少。后续完善:
- 支持 CapsLock / ScrollLock 状态检测
- 加入托盘图标
- 设置自定义快捷键或透明度
- 以及更多自定义功能
欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1701220998@qq.com