inux折腾笔记3:用另一把键盘做快捷键:python脚本

简述问题

拿第二个键盘当全部作快捷键,实现各种功能。

解决过程

无论是win还是linux,解读键盘的指令只会看scancode,就是键盘发送的键位的代码,这个代码显然是各个键盘共用的。现在的问题就是,怎么让系统区分两个键盘? 思路大概有一下集中:

  1. 组合按键,比如把不在键盘上的按键虚拟成一个trigger,任何在这个trigger被按下之后的按键都会被重新解读成一个新的组合键。然后再把这些新的组合键交给autoHotkey来实现各种功能。
  2. 交给专用的软件。
  3. 用脚本监听特定的设备,这里是键盘,然后用脚本来做。

1方案是一个youtube小哥用的,平台是win,结果bug满天飞(主要是用的程序限定了能接的键盘数量,不过现代的键盘一般都会在系统里虚拟出几个键盘来保证稳定。导致经常插usb的话会随机弹飞键盘,只能重启解决。) 2方案有一个lua写的程序,也是面向win的。因为我不会lua所以没有尝试。
总之我在win上的尝试都失败了。然后在搜索的时候偶然看到一篇博文,提到py有在linux下能单独监听一个键盘的库evdev。找来试试果然可以。不过这个库虽然可以模拟按键,用模拟按键的方式输出字符串也太麻烦了。于是搜了搜,有一个叫keyboard的库可以直接输出字符串,以及其他的一些功能(顺带一提这个库是有监听键盘的函数的,不过里面是空的还不能用,不知道这个库的作者还打算做么。)
(再顺带一提这些库的文档真的是简洁,反正我是看不懂。) win上的话有这篇文章,详述了怎么在win里面监听键盘的raw输入。不过我不会C++,所以折腾不来。

结果

总之上代码。

from evdev import InputDevice, categorize, ecodes,list_devices

devices = [InputDevice(path) for path in list_devices()]
for device in devices:
    if device.name=="你的设备的名字."  and  device.phys[-1] == "0":
        path = device.path

dev = InputDevice(path)
dev.grab()
for event in dev.read_loop():
    if event.type == ecodes.EV_KEY:
        key = categorize(event)
        if key.keystate == key.key_down:
#================功能区=============
            if key.keycode == “按键名字":
                功能
            elif key.keycode == “按键名字":
                功能
            elif key.keycode == “按键名字":
                功能

功能在库的文档里都有说明,这里简单说明一下流程。 先在命令行执行python -m evdev.evtest(需要root),可以看到现在有哪些键盘是插着的。找到你要当作快捷键的键盘的名字,记下来。然后把devece.name改成你键盘的名字,OK,环境就搭好了。
然后每个需要定义功能的案件,还是去python -m evdev.evtest,输入自己键盘的input0的event的代号,就能查看每个案件的keycode了。把这个keycode放到功能区的if-elif列里,然后看需要输入自己的命令就好了。 ps. keyboard有一个KeyboardEvent.device,可以区分设备,keyboard.read_key()可以读下个键。

功能的实现

如果是输出字符串的话,keyboard库有个write()方法很不错。 快捷键keyboard里也有。总之详见文档 执行命令的话可以os.system()也可以subprocess.run()。后者功能多一些,也更复杂一点。 另:

dev = InputDevice(path)
dev.grab()

这两句也能拿来屏蔽键盘,和我一样喜欢把键盘直接按到笔记本键盘上的人可以试试。

评论

此博客中的热门博文

Ubuntu修改键盘映射,18.04,gnome

memo xwiki inial