¿Cómo distinguir la entrada de diferentes teclados?


14

Quiero escribir una aplicación en Python que pueda usar con su teclado predeterminado y uno especialmente diseñado para la aplicación. Lo diseñaré simplemente usando un pequeño teclado numérico con pegatinas para dar acciones a las diferentes teclas. Ambos teclados se conectarán por USB.

Sin embargo, cuando se presionan estas teclas, solo se enviarán a Python sus señales regulares (números, operadores y entradas) y no podrá distinguir entre las señales del teclado principal y el teclado especial.

Debido a que Python no tiene (por lo que pude encontrar) ningún método para hacer esta distinción, quiero hacerlo en el sistema operativo en sí. Lo programaré para Raspberry Pi, por lo que será Linux.

Entonces, la pregunta principal: ¿Cómo puedo reasignar las teclas de un teclado específico a otros códigos de teclas? Pensé en usar las teclas F que no usaré para otros fines; o simplemente algunos caracteres que no están presentes en ningún teclado (suponiendo que los haya).

¿Es esto posible en Linux / Unix? Y si es así, ¿cómo puedo hacerlo?


¿Cómo se conectará el teclado? Es posible que desee leer directamente desde el dispositivo. Esa es la forma más obvia para mí, aunque supongo que hay una mejor manera.
TNW

Agregué que se conectarán por USB. ¿Cómo puedo leer directamente desde el dispositivo usando Python?
Steven Roose

Parece que la respuesta no aceptada es mucho más simple que la aceptada.
Nikana Reklawyks

Respuestas:


12

Si usa Linux, la mejor manera de distinguir entre dispositivos de entrada es usar la interfaz de eventos de Linux . Después de decodificar la entrada específica de hardware de un dispositivo, se convierte en una estructura de eventos específica de Linux intermedia y se pone a disposición leyendo uno o más de los dispositivos de caracteres que se encuentran debajo /dev/input/. Por cierto, esto es completamente independiente del lenguaje de programación que usa.

Cada dispositivo de hardware tiene su propio /dev/input/eventXdispositivo, y también hay agregados (por ejemplo, /dev/input/miceque representa el movimiento de todos los ratones en el sistema). Su sistema también puede tener /dev/input/by-pathy /dev/input/by-id.

Hay una ioctlllamada EVIOCGNAMEque devuelve el nombre del dispositivo como una cadena legible por humanos, o puede usar algo como /dev/input/by-id/usb-Logitech_USB_Gaming_Mouse-mouse.

Abre el dispositivo y cada vez que llega un evento desde el hardware de entrada, obtendrá un paquete de datos. Si puede leer C, puede estudiar el archivo /usr/include/linux/input.hque muestra exactamente cómo funciona esto. Si no lo hace, puede leer esta pregunta que proporciona toda la información que necesita.

Lo bueno de la interfaz de eventos es que solo averigua qué dispositivo necesita y puede leer la entrada de ese dispositivo de entrada solo , ignorando todos los demás. También recibirá notificaciones sobre teclas, botones y controles que normalmente no haría simplemente leyendo la secuencia de caracteres 'cocinados' desde un terminal: incluso teclas muertas como Shift, etc.

Lo malo es que la interfaz del evento no devuelve caracteres 'cocinados', solo usa códigos numéricos para las teclas (los códigos correspondientes a cada tecla se encuentran en el archivo de encabezado mencionado anteriormente, pero también en la fuente Python de event.py . Si su dispositivo de entrada tiene teclas / botones inusuales, es posible que deba experimentar un poco hasta obtener los números correctos.


2

Un enfoque alternativo (si su "teclado" no tiene muchas teclas, muchos dispositivos fingen ser teclados) es aplicar una asignación de teclas a cada teclado específicamente y asegurarse de que las teclas se distingan.

Esto se describe aquí: /superuser/760602/how-to-remap-keys-under-linux-for-a-specific-keyboard-only . El punto principal es el setxkbmaptoma un argumento de dispositivo.

Si está utilizando el enfoque de entrada sin formato, lsinput encontrará su dispositivo sin formato por usted.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.