如何区分不同键盘的输入?

如何区分不同键盘的输入?

我想用 Python 编写一个应用程序,您可以使用默认键盘和专门为该应用程序设计的键盘。我将简单地设计它,使用带有贴纸的小型数字键盘来为不同的键提供操作。两个键盘都将通过 USB 连接。

然而,当这些键被按下时,只有它们的常规信号(数字、运算符和输入)将被发送到Python,并且它无法区分来自主键盘和特殊键盘的信号。

因为Python(据我所知)没有方法进行这种区分,所以我想在操作系统本身上进行区分。我将为 Raspberry Pi 进行编程,因此它将是 Linux。

所以,主要问题是:如何将特定键盘的按键重新映射到其他按键代码。我考虑过使用 F 键,但我不会将其用于其他目的;或者只是任何键盘上都不存在的一些字符(假设有这样的字符)。

这在 Linux/Unix 中可能吗?如果是这样,我该怎么做?

答案1

如果您使用的是 Linux,区分输入设备的最佳方法是使用Linux 事件接口。设备的特定于硬件的输入被解码后,它会转换为中间的特定于 Linux 的事件结构,并通过读取 下的一个或多个字符设备使其可用/dev/input/。顺便说一句,这完全独立于您使用的编程语言。

每个硬件设备都有自己的/dev/input/eventX设备,并且还有聚合(例如/dev/input/mice代表系统中所有鼠标的运动)。您的系统可能还具有/dev/input/by-path/dev/input/by-id

有一个ioctl调用EVIOCGNAME将设备名称作为人类可读的字符串返回,或者您可以使用类似/dev/input/by-id/usb-Logitech_USB_Gaming_Mouse-mouse.

您打开设备,每次从输入硬件到达事件时,您都会收到一个数据包。如果你能读懂 C,你就可以研究这个文件/usr/include/linux/input.h,它准确地展示了这个东西是如何工作的。如果你不这样做,你可以阅读这个问题它提供了您需要的所有信息。

事件接口的好处是你只需找出你需要什么设备,就可以从该输入设备读取输入仅有的,忽略所有其他。您还将获得有关按键、按钮和控件的通知,而您通常不会通过仅从终端读取“熟”字符流来获得通知:甚至是死键,例如Shift等。

不好的是,事件接口不会返回“熟”字符,它只是使用数字代码作为键(与每个键对应的代码可以在前面提到的头文件中找到,而且可以在Python源代码中找到)事件.py。如果您的输入设备有不寻常的按键/按钮,您可能需要进行一些尝试,直到获得正确的数字。

答案2

另一种方法(如果您的“键盘”没有很多键 - 许多设备都假装是键盘)是专门对每个键盘应用键映射并确保区分键。

这里概述了这一点:https://superuser.com/questions/760602/how-to-remap-keys-under-linux-for-a-specific-keyboard-only。要点是setxkbmap需要一个设备参数。

如果您使用原始输入方法,lsinput 将为您找到原始设备。

答案3

如果您使用的是 python -埃夫德夫

来自文档:

该包提供了对 Linux 中通用输入事件接口的绑定。 evdev 接口的目的是通过通常位于 /dev/input/ 的字符设备将内核中生成的事件直接传递到用户空间。

该包还附带了对 uinput(用户空间输入子系统)的绑定。 Uinput 允许用户空间程序创建和处理可以将事件直接注入输入子系统的输入设备。

换句话说,python-evdev 允许您在 Linux 上读取和写入输入事件。事件可以是按键或按钮按下、鼠标移动或触摸屏上的点击。

然后在教程页面上...

从多个设备读取事件(使用 select)

>>> from evdev import InputDevice
>>> from select import select

# A mapping of file descriptors (integers) to InputDevice instances.
>>> devices = map(InputDevice, ('/dev/input/event1', '/dev/input/event2'))
>>> devices = {dev.fd: dev for dev in devices}

>>> for dev in devices.values(): print(dev)
device /dev/input/event1, name "Dell Dell USB Keyboard", phys "usb-0000:00:12.1-2/input0"
device /dev/input/event2, name "Logitech USB Laser Mouse", phys "usb-0000:00:12.0-2/input0"

>>> while True:
...    r, w, x = select(devices, [], [])
...    for fd in r:
...        for event in devices[fd].read():
...            print(event)
event at 1351116708.002230, code 01, type 02, val 01
event at 1351116708.002234, code 00, type 00, val 00
event at 1351116708.782231, code 04, type 04, val 458782
event at 1351116708.782237, code 02, type 01, val 01

您可以单独处理每个设备。

相关内容