Jak odróżnić wejście od różnych klawiatur?


14

Chcę napisać aplikację w języku Python, której można używać z domyślną klawiaturą i specjalnie zaprojektowaną dla tej aplikacji. Zaprojektuję to po prostu za pomocą małej klawiatury numerycznej z naklejkami, aby przypisywać różne klawisze. Obie klawiatury zostaną podłączone przez USB.

Jednak po naciśnięciu tych klawiszy tylko ich zwykłe sygnały (cyfry, operatory i wejścia) zostaną wysłane do Pythona i nie będzie w stanie odróżnić sygnałów z klawiatury głównej i klawiatury specjalnej.

Ponieważ Python (o ile mogłem znaleźć) nie ma metody na dokonanie tego rozróżnienia, chcę to zrobić w samym systemie operacyjnym. Będę programował to dla Raspberry Pi, więc będzie to Linux.

Tak więc główne pytanie: Jak mogę przypisać klawisze określonej klawiatury do innych kodów. Pomyślałem o użyciu klawiszy F, których nie użyję do innych celów; lub tylko niektóre znaki, które nie są obecne na żadnej klawiaturze (zakładając, że takie istnieją).

Czy jest to możliwe w systemie Linux / Unix? A jeśli tak, jak mogę to zrobić?


Jak będzie podłączana klawiatura? Możesz przeczytać bezpośrednio z urządzenia. To dla mnie najbardziej oczywisty sposób, choć przypuszczam, że istnieje lepszy sposób.
TNW

Dodałem, że połączą się przez USB. Jak mogę czytać bezpośrednio z urządzenia za pomocą Pythona?
Steven Roose

Wygląda na to, że nieakceptowana odpowiedź jest o wiele prostsza niż zaakceptowana.
Nikana Reklawyks

Odpowiedzi:


12

Jeśli używasz Linuksa, najlepszym sposobem na rozróżnienie urządzeń wejściowych jest użycie Linuksowego interfejsu zdarzeń . Po zdekodowaniu danych wejściowych specyficznych dla urządzenia, jest ono przekształcane w pośrednią strukturę zdarzeń specyficzną dla Linuksa i udostępniane przez odczyt jednego lub więcej urządzeń znakowych pod /dev/input/. Nawiasem mówiąc, jest to całkowicie niezależne od używanego języka programowania.

Każde urządzenie sprzętowe otrzymuje własne /dev/input/eventXurządzenie, a także agregaty (np. /dev/input/miceReprezentujące ruch wszystkich myszy w systemie). Twój system może również mieć /dev/input/by-pathi /dev/input/by-id.

Istnieje ioctlwywołanie, EVIOCGNAMEktóre zwraca nazwę urządzenia jako ciąg czytelny dla człowieka lub można użyć czegoś takiego /dev/input/by-id/usb-Logitech_USB_Gaming_Mouse-mouse.

Otwierasz urządzenie i za każdym razem, gdy zdarzenie przychodzi ze sprzętu wejściowego, otrzymasz pakiet danych. Jeśli umiesz czytać w C, możesz przestudiować plik, /usr/include/linux/input.hktóry dokładnie pokazuje, jak to działa. Jeśli nie, możesz przeczytać to pytanie, które zawiera wszystkie potrzebne informacje.

Dobrą rzeczą w interfejsie zdarzeń jest to, że po prostu dowiadujesz się, jakiego urządzenia potrzebujesz, i możesz czytać dane wejściowe tylko z tego urządzenia wejściowego , ignorując wszystkie inne. Otrzymasz również powiadomienia o klawiszach, przyciskach i kontrolkach, których normalnie byś nie czytał, po prostu czytając „gotowany” strumień znaków z terminala: nawet martwe klawisze Shift, itp.

Złą rzeczą jest to, że interfejs zdarzeń nie zwraca „gotowanych” znaków, po prostu używa kodów numerycznych dla kluczy (kody odpowiadające każdemu kluczowi znajdują się we wspomnianym pliku nagłówkowym - ale także w źródle pliku event.py w Pythonie . Jeśli twoje urządzenie wejściowe ma nietypowe klawisze / przyciski, być może trzeba trochę poeksperymentować, aż uzyskasz odpowiednie liczby.


2

Alternatywnym podejściem (jeśli twoja „klawiatura” nie ma wielu klawiszy - wiele urządzeń udaje, że są klawiaturami), to zastosowanie mapowania klawiatury do każdej klawiatury i upewnienie się, że klawisze są rozróżniane.

Jest to opisane tutaj: /superuser/760602/how-to-remap-keys-under-linux-for-a-specific-keyboard-only . Głównym punktem jest setxkbmapargument urządzenia.

Jeśli używasz metody surowego wprowadzania, lsinput znajdzie dla ciebie surowe urządzenie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.