Come distinguere l'input da diverse tastiere?


14

Voglio scrivere un'applicazione in Python che puoi usare con la tua tastiera predefinita e una appositamente progettata per l'applicazione. Lo progetterò semplicemente usando una piccola tastiera numerica con adesivi per dare azioni ai diversi tasti. Entrambe le tastiere saranno collegate tramite USB.

Tuttavia, quando si premono questi tasti, solo i loro segnali regolari (numeri, operatori ed inserimenti) verranno inviati a Python e non sarà in grado di distinguere tra i segnali dalla tastiera principale e quella speciale.

Poiché Python non ha (per quanto ho potuto trovare) alcun metodo per fare questa distinzione, voglio farlo sul sistema operativo stesso. Lo programmerò per il Raspberry Pi, quindi sarà Linux.

Quindi, la domanda principale: come posso rimappare i tasti di una tastiera specifica ad altri codici chiave. Ho pensato di usare i tasti F che non userò per altri scopi; o solo alcuni caratteri che non sono presenti su nessuna tastiera (supponendo che ce ne siano).

È possibile in Linux / Unix? E se è così, come posso farlo?


Come verrà collegata la tastiera? Potresti voler leggere direttamente dal dispositivo. Questo è il modo più ovvio per me, anche se suppongo che ci sia un modo migliore.
TNW,

Ho aggiunto che si collegheranno tramite USB. Come posso leggere direttamente dal dispositivo usando Python?
Steven Roose,

Sembra che la risposta non accettata sia molto più semplice di quella accettata.
Nikana Reklawyks il

Risposte:


12

Se stai usando Linux, il modo migliore per distinguere i dispositivi di input è usare l' interfaccia degli eventi di Linux . Dopo la decodifica dell'input specifico dell'hardware di un dispositivo, questo viene convertito in una struttura di eventi specifica specifica di Linux intermedia e reso disponibile leggendo uno o più dei dispositivi carattere sotto /dev/input/. Questo è completamente indipendente dal linguaggio di programmazione che usi, tra l'altro.

Ogni dispositivo hardware ottiene il proprio /dev/input/eventXdispositivo e ci sono anche aggregati (ad esempio, /dev/input/miceche rappresenta il movimento di tutti i mouse nel sistema). Il tuo sistema potrebbe anche avere /dev/input/by-pathe /dev/input/by-id.

C'è un ioctlchiamato EVIOCGNAMEche restituisce il nome del dispositivo come una stringa leggibile umanamente, oppure puoi usare qualcosa del genere /dev/input/by-id/usb-Logitech_USB_Gaming_Mouse-mouse.

Apri il dispositivo e ogni volta che arriva un evento dall'hardware di input, otterrai un pacchetto di dati. Se riesci a leggere C, puoi studiare il file /usr/include/linux/input.hche mostra esattamente come funziona questa roba. In caso contrario, è possibile leggere questa domanda che fornisce tutte le informazioni necessarie.

La cosa buona di l'interfaccia di eventi è che basta scoprire quale dispositivo hai bisogno, e si può leggere l'input da quel dispositivo di input solo , ignorando tutti gli altri. Riceverai anche notifiche su tasti, pulsanti e controlli che normalmente non avresti semplicemente leggendo il flusso di caratteri "cotti" da un terminale: anche chiavi morte come Shift, ecc.

La cosa brutta è che l'interfaccia dell'evento non restituisce caratteri "cotti", usa solo codici numerici per le chiavi (i codici corrispondenti a ciascuna chiave si trovano nel file di intestazione sopra menzionato - ma anche nella fonte Python di event.py . Se il tuo dispositivo di input ha tasti / pulsanti insoliti, potresti dover provare un po 'fino a ottenere i numeri giusti.


2

Un approccio alternativo (se la tua "tastiera" non ha molti tasti - molti dispositivi fingono di essere tastiere) è applicare un keymapping a ciascuna tastiera in modo specifico e assicurarsi che i tasti siano distinti.

Questo è delineato qui: /superuser/760602/how-to-remap-keys-under-linux-for-a-specific-keyboard-only . Il punto principale è il setxkbmapprende un argomento dispositivo.

Se stai utilizzando l'approccio di input non elaborato, lsinput troverà il tuo dispositivo raw per te.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.