Como distinguir entrada de diferentes teclados?


14

Quero escrever um aplicativo em Python que você possa usar com o teclado padrão e um especialmente projetado para o aplicativo. Vou projetá-lo simplesmente usando um pequeno teclado numérico com adesivos para dar ações às diferentes teclas. Ambos os teclados serão conectados por USB.

No entanto, quando essas teclas são pressionadas, apenas os sinais regulares (números, operadores e entradas) serão enviados para o Python e não será possível distinguir entre os sinais do teclado principal e do teclado especial.

Como o Python (até onde eu pude encontrar) não tem método para fazer essa distinção, eu quero fazê-lo no próprio sistema operacional. Vou programá-lo para o Raspberry Pi, então será o Linux.

Portanto, a principal questão: como remapear as teclas de um teclado específico para outros códigos de teclas. Pensei em usar as teclas F que não usarei para outros fins; ou apenas alguns caracteres que não estão presentes em nenhum teclado (supondo que existam).

Isso é possível no Linux / Unix? E se sim, como posso fazer isso?


Como o teclado será conectado? Você pode querer ler diretamente do dispositivo. Essa é a maneira mais óbvia para mim, embora eu suponha que haja uma maneira melhor.
TNW15 de

Eu adicionei que eles vão se conectar por USB. Como posso ler diretamente do dispositivo usando Python?
precisa saber é o seguinte

Parece que a resposta não aceita é muito mais simples que a resposta aceita.
Nikola Reklawyks

Respostas:


12

Se você estiver usando Linux, a melhor maneira de distinguir entre dispositivos de entrada é usar a Interface de Eventos do Linux . Depois que a entrada específica de hardware de um dispositivo é decodificada, ela é convertida em uma estrutura de eventos específica do Linux intermediária e disponibilizada pela leitura de um ou mais dos dispositivos de caracteres abaixo /dev/input/. A propósito, isso é completamente independente da linguagem de programação usada.

Cada dispositivo de hardware obtém seu próprio /dev/input/eventXdispositivo e também há agregados (por exemplo, o /dev/input/miceque representa o movimento de todos os mouses no sistema). Seu sistema também pode ter /dev/input/by-pathe /dev/input/by-id.

Existe um ioctlchamado EVIOCGNAMEque retorna o nome do dispositivo como uma sequência legível por humanos, ou você pode usar algo parecido /dev/input/by-id/usb-Logitech_USB_Gaming_Mouse-mouse.

Você abre o dispositivo e toda vez que um evento chega do hardware de entrada, você recebe um pacote de dados. Se você pode ler C, pode estudar o arquivo /usr/include/linux/input.hque mostra exatamente como essas coisas funcionam. Caso contrário, você pode ler esta pergunta, que fornece todas as informações necessárias.

A coisa boa sobre a interface do evento é que você acaba de descobrir de que dispositivo precisa e pode ler as entradas apenas desse dispositivo , ignorando todas as outras. Você também receberá notificações sobre teclas, botões e controles que normalmente não leria apenas o fluxo de caracteres 'cozidos' de um terminal: até mesmo chaves mortas Shift, etc.

O ruim é que a interface do evento não retorna caracteres 'cozidos', apenas usa códigos numéricos para as chaves (os códigos correspondentes a cada chave são encontrados no arquivo de cabeçalho mencionado acima - mas também na fonte de event.py do Python . Se o seu dispositivo de entrada tiver teclas / botões incomuns, talvez seja necessário experimentar um pouco até obter os números certos.


2

Uma abordagem alternativa (se o seu "teclado" não tiver muitas teclas - muitos dispositivos fingem ser teclados) é aplicar um mapeamento de teclas a cada teclado especificamente e garantir que as teclas sejam diferenciadas.

Isso é descrito aqui: /superuser/760602/how-to-remap-keys-under-linux-for-a-specific-keyboard-only . O ponto principal é o setxkbmapargumento de um dispositivo.

Se você estiver usando a abordagem de entrada bruta, o lsinput encontrará seu dispositivo bruto para você.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.