저는 기본 키보드와 해당 애플리케이션을 위해 특별히 설계된 키보드를 사용할 수 있는 애플리케이션을 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 소스 코드에서 찾을 수 있습니다).events.py. 입력 장치에 특이한 키/버튼이 있는 경우 올바른 숫자를 얻을 때까지 약간의 실험이 필요할 수 있습니다.
답변2
또 다른 접근 방식("키보드"에 키가 많지 않은 경우 - 많은 장치가 키보드인 척하는 경우)은 각 키보드에 특별히 키맵을 적용하고 키가 구별되는지 확인하는 것입니다.
이에 대한 설명은 다음과 같습니다.https://superuser.com/questions/760602/how-to-remap-keys-under-linux-for-a-specific-keyboard-only. 중요한 점은 setxkbmap
장치 매개변수가 필요하다는 것입니다.
원시 입력 방법을 사용하는 경우 lsinput이 원시 장치를 찾습니다.
답변3
파이썬을 사용하는 경우 -evdev
문서에서:
이 패키지는 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
각 장치를 개별적으로 처리할 수 있습니다.